text: /* @flow */
  /** ** firebase ****/
  
  declare interface $npm$firebase$Config {
    apiKey: string;
    authDomain?: string;
    databaseURL?: string;
    projectId?: string;
    storageBucket?: string;
    messagingSenderId?: string;
  }
  
  declare interface $npm$firebase$auth$Error {
    code:
      | 'auth/app-deleted'
      | 'auth/app-not-authorized'
      | 'auth/argument-error'
      | 'auth/invalid-api-key'
      | 'auth/invalid-user-token'
      | 'auth/network-request-failed'
      | 'auth/operation-not-allowed'
      | 'auth/requires-recent-login'
      | 'auth/too-many-requests'
      | 'auth/unauthorized-domain'
      | 'auth/user-disabled'
      | 'auth/user-token-expired'
      | 'auth/web-storage-unsupported'
      | 'auth/invalid-email'
      | 'auth/account-exists-with-different-credential'
      | 'auth/invalid-credential'
      | 'auth/user-not-found'
      | 'auth/wrong-password'
      | 'auth/invalid-verification-code'
      | 'auth/invalid-verification-id'
      | 'auth/expired-action-code'
      | 'auth/invalid-action-code'
      | 'auth/invalid-verification-code'
      | 'auth/missing-verification-code'
      | 'auth/captcha-check-failed'
      | 'auth/invalid-phone-number'
      | 'auth/missing-phone-number'
      | 'auth/quota-exceeded'
      | 'auth/credential-already-in-use'
      | 'auth/email-already-in-use'
      | 'auth/provider-already-linked'
      | 'auth/auth-domain-config-required'
      | 'auth/cancelled-popup-request'
      | 'auth/popup-blocked'
      | 'auth/operation-not-supported-in-this-environment'
      | 'auth/popup-closed-by-user'
      | 'auth/unauthorized-domain'
      | 'auth/no-such-provider';
    message: string;
  }
  
  declare interface $npm$firebase$Error {
    code: $PropertyType<$npm$firebase$auth$Error, 'code'> | 'app/no-app';
    message: string;
    name: string;
    stack: ?string;
  }
  
  /** *** app *****/
  declare class $npm$firebase$App {
    name: string;
    +options: $npm$firebase$Config;
    auth(): $npm$firebase$auth$Auth;
    database(): $npm$firebase$database$Database;
    storage(): $npm$firebase$storage$Storage;
    delete(): Promise<void>;
  }
  
  /** **** auth *******/
  declare interface $npm$firebase$auth$ActionCodeInfo {
    data: { email: string };
  }
  
  declare interface $npm$firebase$auth$ApplicationVerifier {
    type: string;
    verify(): Promise<string>;
  }
  
  declare type $npm$firebase$auth$Auth$Persistence = {
    +LOCAL: 'local',
    +SESSION: 'session',
    +NONE: 'none',
  }
  
  declare type $npm$firebase$auth$Auth$Persistence$Enum = $Values<$npm$firebase$auth$Auth$Persistence>
  
  declare class $npm$firebase$auth$Auth {
    static Persistence: $npm$firebase$auth$Auth$Persistence;
    app: $npm$firebase$App;
    currentUser: $npm$firebase$auth$User;
    applyActionCode(code: string): Promise<void>;
    checkActionCode(code: string): Promise<$npm$firebase$auth$ActionCodeInfo>;
    confirmPasswordReset(code: string, newPassword: string): Promise<void>;
    createCustomToken(uid: string, developerClaims?: {}): string;
    createUserWithEmailAndPassword(
      email: string,
      password: string
    ): Promise<$npm$firebase$auth$User>;
    fetchProvidersForEmail(email: string): Promise<Array<string>>;
    onAuthStateChanged(
      nextOrObserver: (?$npm$firebase$auth$User) => void | Promise<void>,
      error?: (error: $npm$firebase$auth$Error) => void,
      completed?: () => void
    ): () => void;
    onIdTokenChanged(
      nextOrObserver: Object | ((user?: $npm$firebase$auth$User) => void | Promise<void>),
      error?: (error: $npm$firebase$auth$Error) => void,
      completed?: () => void
    ): () => void;
    sendPasswordResetEmail(email: string): Promise<void>;
    setPersistence(persistence: $npm$firebase$auth$Auth$Persistence$Enum): Promise<void>;
    signInAndRetrieveDataWithCredential(
      credential: $npm$firebase$auth$AuthCredential
    ): Promise<$npm$firebase$auth$UserCredential>;
    signInAnonymously(): Promise<$npm$firebase$auth$User>;
    signInWithCredential(
      credential: $npm$firebase$auth$AuthCredential
    ): Promise<$npm$firebase$auth$User>;
    signInWithCustomToken(token: string): Promise<$npm$firebase$auth$User>;
    signInWithEmailAndPassword(
      email: string,
      password: string
    ): Promise<$npm$firebase$auth$User>;
    signInWithPhoneNumber(
      phoneNumber: string,
      applicationVerifier: $npm$firebase$auth$ApplicationVerifier
    ): Promise<$npm$firebase$auth$ConfirmationResult>;
    signInWithPopup(
      provider: $npm$firebase$auth$AuthProvider
    ): Promise<$npm$firebase$auth$UserCredential>;
    signOut(): Promise<void>;
    verifyIdToken(idToken: string): Promise<Object>;
    verifyPasswordResetCode(code: string): Promise<string>;
  }
  
  declare interface $npm$firebase$auth$AuthCredential {
    providerId: string;
  }
  
  declare class $npm$firebase$auth$AuthProvider {
    providerId: string;
  }
  
  declare interface $npm$firebase$auth$ConfirmationResult {
    verificationId: string;
    confirm(verificationCode: string): Promise<$npm$firebase$auth$UserCredential>;
  }
  
  declare type $npm$firebase$auth$UserProfile = {
    displayName?: string,
    photoURL?: string
  };
  
  declare interface $npm$firebase$auth$AdditionalUserInfo {
    providerId: string;
    profile?: $npm$firebase$auth$UserProfile;
    username?: string;
  }
  
  declare interface $npm$firebase$auth$UserCredential {
    user: $npm$firebase$auth$User;
    credential?: $npm$firebase$auth$AuthCredential;
    operationType?: string;
    additionalUserInfo?: $npm$firebase$auth$AdditionalUserInfo;
  }
  
  declare class $npm$firebase$auth$UserInfo {
    displayName: ?string;
    email: ?string;
    photoURL: ?string;
    providerId: string;
    uid: string;
  }
  
  declare type $npm$firebase$actionCode$settings = {
    url: string,
    iOS?: { bundleId: string },
    android?: {
      packageName: string,
      installApp?: boolean,
      minimumVersion?: string,
    },
    handleCodeInApp?: boolean,
  }
  
  declare class $npm$firebase$auth$User extends $npm$firebase$auth$UserInfo {
    displayName: ?string;
    email: ?string;
    emailVerified: boolean;
    isAnonymous: boolean;
    phoneNumber: ?string;
    photoUrl: ?string;
    providerData: Array<$npm$firebase$auth$UserInfo>;
    providerId: string;
    refreshToken: string;
    uid: string;
    delete(): Promise<void>;
    getIdToken(forceRefresh?: boolean): Promise<string>;
    getToken(forceRefresh?: boolean): Promise<string>;
    linkAndRetrieveDataWithCredential(
      credential: $npm$firebase$auth$AuthCredential
    ): Promise<$npm$firebase$auth$UserCredential>;
    linkWithCredential(
      credential: $npm$firebase$auth$AuthCredential
    ): Promise<$npm$firebase$auth$User>;
    linkWithPhoneNumber(
      phoneNumber: string,
      applicationVerifier: $npm$firebase$auth$ApplicationVerifier
    ): Promise<$npm$firebase$auth$ConfirmationResult>;
    linkWithPopup(
      provider: $npm$firebase$auth$OAuthProvider
    ): Promise<$npm$firebase$auth$UserCredential>;
    reauthenticateAndRetrieveDataWithCredential(
      credential: $npm$firebase$auth$AuthCredential
    ): Promise<void>;
    reauthenticateWithCredential(
      credential: $npm$firebase$auth$AuthCredential
    ): Promise<void>;
    reauthenticateWithPhoneNumber(
      phoneNumber: string,
      applicationVerifier: $npm$firebase$auth$ApplicationVerifier
    ): Promise<$npm$firebase$auth$ConfirmationResult>;
    reload(): Promise<void>;
    sendEmailVerification(actionCodeSettings?: $npm$firebase$actionCode$settings): Promise<void>;
    toJSON(): Object;
    unlink(providerId: string): Promise<$npm$firebase$auth$User>;
    updateEmail(newEmail: string): Promise<void>;
    updatePassword(newPassword: string): Promise<void>;
    updatePhoneNumber(
      phoneCredential: $npm$firebase$auth$AuthCredential
    ): Promise<void>;
    updateProfile(profile: $npm$firebase$auth$UserProfile): Promise<void>;
  }
  
  declare class $npm$firebase$auth$EmailAuthProvider extends $npm$firebase$auth$AuthProvider {
    PROVIDER_ID: string;
    providerId: string;
    credential(
      email: string,
      password: string
    ): $npm$firebase$auth$AuthCredential;
  }
  
  declare class $npm$firebase$auth$FacebookAuthProvider extends $npm$firebase$auth$AuthProvider {
    PROVIDER_ID: string;
    credential(token: string): $npm$firebase$auth$AuthCredential;
    addScope(scope: string): $npm$firebase$auth$FacebookAuthProvider;
    setCustomParameters(
      customOAuthParameters: Object
    ): $npm$firebase$auth$FacebookAuthProvider;
  }
  
  declare class $npm$firebase$auth$GithubAuthProvider extends $npm$firebase$auth$AuthProvider {
    PROVIDER_ID: string;
    credential(token: string): $npm$firebase$auth$AuthCredential;
    addScope(scope: string): $npm$firebase$auth$GithubAuthProvider;
    setCustomParameters(
      customOAuthParameters: Object
    ): $npm$firebase$auth$GithubAuthProvider;
  }
  
  declare class $npm$firebase$auth$GoogleAuthProvider extends $npm$firebase$auth$AuthProvider {
    PROVIDER_ID: string;
    credential(
      idToken?: string,
      accessToken?: string
    ): $npm$firebase$auth$AuthCredential;
    addScope(scope: string): $npm$firebase$auth$GoogleAuthProvider;
    setCustomParameters(
      customOAuthParameters: Object
    ): $npm$firebase$auth$GoogleAuthProvider;
  }
  
  declare class $npm$firebase$auth$PhoneAuthProvider extends $npm$firebase$auth$AuthProvider {
    PROVIDER_ID: string;
    constructor(
      auth?: $npm$firebase$auth$Auth
    ): $npm$firebase$auth$PhoneAuthProvider;
    credential(
      verificationId: string,
      verificationCode: string
    ): $npm$firebase$auth$AuthCredential;
    verifyPhoneNumber(
      phoneNumber: string,
      applicationVerifier: $npm$firebase$auth$ApplicationVerifier
    ): Promise<string>;
  }
  
  declare class $npm$firebase$auth$TwitterAuthProvider extends $npm$firebase$auth$AuthProvider {
    PROVIDER_ID: string;
    credential(token: string, secret: string): $npm$firebase$auth$AuthCredential;
    setCustomParameters(customOAuthParameters: Object): this;
  }
  
  declare type $npm$firebase$auth$OAuthProvider =
    | $npm$firebase$auth$FacebookAuthProvider
    | $npm$firebase$auth$GithubAuthProvider
    | $npm$firebase$auth$GoogleAuthProvider
    | $npm$firebase$auth$TwitterAuthProvider;
  
  /** **** database ******/
  declare type $npm$firebase$database$Value = any;
  declare type $npm$firebase$database$OnCompleteCallback = (
    error: ?Object
  ) => void;
  declare type $npm$firebase$database$QueryEventType =
    | 'value'
    | 'child_added'
    | 'child_changed'
    | 'child_removed'
    | 'child_moved';
  declare type $npm$firebase$database$Priority = string | number | null;
  
  declare class $npm$firebase$database$Database {
    app: $npm$firebase$App;
    goOffline(): void;
    goOnline(): void;
    ref(path?: string): $npm$firebase$database$Reference;
    refFromURL(url: string): $npm$firebase$database$Reference;
  }
  
  declare class $npm$firebase$database$DataSnapshot {
    key: ?string;
    ref: $npm$firebase$database$Reference;
    child(path?: string): $npm$firebase$database$DataSnapshot;
    exists(): boolean;
    exportVal(): $npm$firebase$database$Value;
    forEach(action: ($npm$firebase$database$DataSnapshot) => boolean): boolean;
    getPriority(): $npm$firebase$database$Priority;
    hasChild(path: string): boolean;
    hasChildren(): boolean;
    numChildren(): number;
    toJSON(): Object;
    val(): $npm$firebase$database$Value;
  }
  
  declare class $npm$firebase$database$OnDisconnect {
    cancel(onComplete?: $npm$firebase$database$OnCompleteCallback): Promise<void>;
    remove(onComplete?: $npm$firebase$database$OnCompleteCallback): Promise<void>;
    set(
      value: $npm$firebase$database$Value,
      onComplete?: $npm$firebase$database$OnCompleteCallback
    ): Promise<void>;
    setWithPriority(
      value: $npm$firebase$database$Value,
      priority: number | string | null,
      onComplete?: $npm$firebase$database$OnCompleteCallback
    ): Promise<void>;
    update(
      values: { +[path: string]: $npm$firebase$database$Value },
      onComplete?: $npm$firebase$database$OnCompleteCallback
    ): Promise<void>;
  }
  
  declare type $npm$firebase$database$Callback = (
    $npm$firebase$database$DataSnapshot,
    ?string
  ) => void;
  
  declare class $npm$firebase$database$Query {
    ref: $npm$firebase$database$Reference;
    endAt(
      value: number | string | boolean | null,
      key?: string
    ): $npm$firebase$database$Query;
    equalTo(
      value: number | string | boolean | null,
      key?: string
    ): $npm$firebase$database$Query;
    isEqual(other: $npm$firebase$database$Query): boolean;
    limitToFirst(limit: number): $npm$firebase$database$Query;
    limitToLast(limit: number): $npm$firebase$database$Query;
    off(
      eventType?: $npm$firebase$database$QueryEventType,
      callback?: $npm$firebase$database$Callback,
      context?: Object
    ): void;
    on(
      eventType: $npm$firebase$database$QueryEventType,
      callback: $npm$firebase$database$Callback,
      cancelCallbackOrContext?: (error: Object) => void | Object,
      context?: $npm$firebase$database$Callback
    ): $npm$firebase$database$Callback;
    once(
      eventType: $npm$firebase$database$QueryEventType,
      successCallback?: $npm$firebase$database$Callback,
      failureCallbackOrContext?: (error: Object) => void | Object,
      context?: Object
    ): Promise<$npm$firebase$database$DataSnapshot>;
    orderByChild(path: string): $npm$firebase$database$Query;
    orderByKey(): $npm$firebase$database$Query;
    orderByPriority(): $npm$firebase$database$Query;
    orderByValue(): $npm$firebase$database$Query;
    startAt(
      value: number | string | boolean | null,
      key?: string
    ): $npm$firebase$database$Query;
    toJSON(): Object;
    toString(): string;
  }
  
  declare class $npm$firebase$database$Reference extends $npm$firebase$database$Query {
    key: ?string;
    parent?: $npm$firebase$database$Reference;
    root: $npm$firebase$database$Reference;
    child(path: string): $npm$firebase$database$Reference;
    onDisconnect(): $npm$firebase$database$OnDisconnect;
    push(
      value?: $npm$firebase$database$Value,
      onComplete?: $npm$firebase$database$OnCompleteCallback
    ): $npm$firebase$database$ThenableReference & Promise<void>;
    remove(onComplete?: $npm$firebase$database$OnCompleteCallback): Promise<void>;
    set(
      value: $npm$firebase$database$Value,
      onComplete?: $npm$firebase$database$OnCompleteCallback
    ): Promise<void>;
    setPriority(
      priority: $npm$firebase$database$Priority,
      onComplete?: $npm$firebase$database$OnCompleteCallback
    ): Promise<void>;
    setWithPriority(
      newVal: $npm$firebase$database$Value,
      newPriority: $npm$firebase$database$Priority,
      onComplete?: $npm$firebase$database$OnCompleteCallback
    ): Promise<void>;
    transaction(
      transactionUpdate: (
        data: $npm$firebase$database$Value
      ) => $npm$firebase$database$Value,
      onComplete?: (
        error: null | Object,
        committed: boolean,
        snapshot: $npm$firebase$database$DataSnapshot
      ) => void,
      applyLocally?: boolean
    ): Promise<{
      committed: boolean,
      snapshot: $npm$firebase$database$DataSnapshot | null
    }>;
    update(
      values: { [path: string]: $npm$firebase$database$Value },
      onComplete?: $npm$firebase$database$OnCompleteCallback
    ): Promise<void>;
  }
  
  declare class $npm$firebase$database$ServerValue {
    static TIMESTAMP: {};
  }
  
  declare class $npm$firebase$database$ThenableReference extends $npm$firebase$database$Reference {}
  
  /** **** firestore ******/
  declare class $npm$firebase$firestore$Firestore {
    app: $npm$firebase$App;
    batch(): $npm$firebase$firestore$WriteBatch;
    collection(collectionPath: string): $npm$firebase$firestore$CollectionReference;
    doc(documentPath: string): $npm$firebase$firestore$DocumentReference;
    enablePersistence(): Promise<void>;
    runTransaction(updateFunction: (transaction: $npm$firebase$firestore$Transaction) => Promise<any>): Promise<mixed>;
    setLogLevel(logLevel: 'debug' | 'error' | 'silent'): void;
    settings(settings: $npm$firebase$firestore$Settings): void;
  }
  
  declare interface $npm$firebase$firestore$Blob {
    fromBase64String(base64: string): $npm$firebase$firestore$Blob;
    fromUint8Array(array: Uint8Array): $npm$firebase$firestore$Blob;
    toBase64(): string;
    toUintArray(): Uint8Array;
  }
  
  declare interface $npm$firebase$firestore$QueryListenOptions {
    includeMetadataChanges: boolean;
    includeQueryMetadataChanges: boolean;
  }
  declare type $npm$firebase$firestore$observer = (snapshot: $npm$firebase$firestore$DocumentSnapshot) => void;
  declare type $npm$firebase$firestore$observerError = (error: $npm$firebase$Error) => void;
  
  declare class $npm$firebase$firestore$Query {
    firestore: $npm$firebase$firestore$Firestore;
    endAt(snapshotOrVarArgs: $npm$firebase$firestore$DocumentSnapshot | {}): $npm$firebase$firestore$Query;
    endBefore(snapshotOrVarArgs: $npm$firebase$firestore$DocumentSnapshot | {}): $npm$firebase$firestore$Query;
    get(): Promise<$npm$firebase$firestore$QuerySnapshot>;
    limit(limit: number): $npm$firebase$firestore$Query;
    onSnapshot(
      optionsOrObserverOrOnNext: $npm$firebase$firestore$QueryListenOptions | $npm$firebase$firestore$observer,
      observerOrOnNextOrOnError?: | $npm$firebase$firestore$QueryListenOptions
      | $npm$firebase$firestore$observer
      | $npm$firebase$firestore$observerError,
      onError?: $npm$firebase$firestore$observerError
    ): void;
    orderBy(
      fieldPath: $npm$firebase$firestore$FieldPath | string,
      directionStr: 'asc' | 'desc'
    ): $npm$firebase$firestore$Query;
    startAfter(snapshotOrVarArgs: $npm$firebase$firestore$DocumentSnapshot | {}): $npm$firebase$firestore$Query;
    startAt(snapshotOrVarArgs: $npm$firebase$firestore$DocumentSnapshot | {}): $npm$firebase$firestore$Query;
    where(fieldPath: string, opStr: '<' | '<=' | '==' | '>' | '>=', value: any): $npm$firebase$firestore$Query;
  }
  
  declare class $npm$firebase$firestore$CollectionReference extends $npm$firebase$firestore$Query {
    constructor(): $npm$firebase$firestore$CollectionReference;
    id: string;
    parent: $npm$firebase$firestore$DocumentReference | null;
    add(data: {}): Promise<mixed>;
    doc(documentPath?: string): $npm$firebase$firestore$DocumentReference;
  }
  
  declare interface $npm$firebase$firestore$DocumentChange {
    type: 'added' | 'removed' | 'modified';
  }
  
  declare class $npm$firebase$firestore$DocumentReference {
    firestore: $npm$firebase$firestore$Firestore;
    id: string;
    parent: typeof $npm$firebase$firestore$CollectionReference;
    collection(collectionPath: string): typeof $npm$firebase$firestore$CollectionReference;
    delete(): Promise<void>;
    get(): Promise<$npm$firebase$firestore$DocumentSnapshot>;
    onSnapshot(
      optionsOrObserverOrOnNext: $npm$firebase$firestore$QueryListenOptions | $npm$firebase$firestore$observer,
      observerOrOnNextOrOnError?: | $npm$firebase$firestore$QueryListenOptions
      | $npm$firebase$firestore$observer
      | $npm$firebase$firestore$observerError,
      onError?: $npm$firebase$firestore$observerError
    ): void;
    set(data: {}, options?: { merge: boolean } | null): Promise<void>;
    update(...args: Array<any>): Promise<void>;
  }
  
  declare class $npm$firebase$firestore$DocumentSnapshot {
    data(): {};
    get(fieldpath: typeof $npm$firebase$firestore$FieldPath): any;
    exists: boolean;
    id: string;
    metadata: $npm$firebase$firestore$SnapshotMetadata;
    ref: $npm$firebase$firestore$DocumentReference;
  }
  
  declare class $npm$firebase$firestore$FieldPath {
    constructor(...args: Array<any>): $npm$firebase$firestore$FieldPath;
    documentId(): typeof $npm$firebase$firestore$FieldPath;
  }
  
  declare interface $npm$firebase$firestore$FieldValue {
    delete(): $npm$firebase$firestore$FieldValue;
    serverTimestamp(): $npm$firebase$firestore$FieldValue;
  }
  
  declare type $npm$firebase$firestore$FirestoreError =
    | 'cancelled'
    | 'unknown'
    | 'invalid-argument'
    | 'deadline-exceeded'
    | 'not-found'
    | 'already-exists'
    | 'permission-denied'
    | 'resource-exhausted'
    | 'failed-precondition'
    | 'aborted'
    | 'out-of-range'
    | 'unimplemented'
    | 'internal'
    | 'unavailable'
    | 'data-loss'
    | 'unauthenticated';
  
  declare class $npm$firebase$firestore$GeoPoint {
    constructor(latitude: number, longitude: number): $npm$firebase$firestore$GeoPoint;
    latitude: number;
    longitude: number;
  }
  
  declare class $npm$firebase$firestore$QuerySnapshot {
    docChanges(): Array<$npm$firebase$firestore$DocumentChange>;
    docs: Array<$npm$firebase$firestore$DocumentSnapshot>;
    empty: boolean;
    metadata: $npm$firebase$firestore$SnapshotMetadata;
    query: $npm$firebase$firestore$Query;
    size: number;
    forEach((snapshot: $npm$firebase$firestore$DocumentSnapshot, thisArg?: any) => void): void;
  }
  
  declare interface $npm$firebase$firestore$Settings {}
  
  declare interface $npm$firebase$firestore$SnapshotMetadata {
    fromCache: boolean;
    hasPendingWrites: boolean;
  }
  
  declare interface $npm$firebase$firestore$Transaction {
    delete(documentRef: $npm$firebase$firestore$DocumentReference): $npm$firebase$firestore$Transaction;
    get(documentRef: $npm$firebase$firestore$DocumentReference): Promise<$npm$firebase$firestore$DocumentSnapshot>;
    set(
      documentRef: $npm$firebase$firestore$DocumentReference,
      data: {},
      options?: { merge: boolean }
    ): $npm$firebase$firestore$Transaction;
    update(documentRef: $npm$firebase$firestore$DocumentReference, ...args: Array<any>): $npm$firebase$firestore$Transaction;
  }
  
  declare interface $npm$firebase$firestore$WriteBatch {
    commit(): Promise<void>;
    delete(documentRef: $npm$firebase$firestore$DocumentReference): $npm$firebase$firestore$WriteBatch;
    set(
      documentRef: $npm$firebase$firestore$DocumentReference,
      data: {},
      options?: { merge: boolean }
    ): $npm$firebase$firestore$WriteBatch;
    update(documentRef: $npm$firebase$firestore$DocumentReference, ...args: Array<any>): $npm$firebase$firestore$WriteBatch;
  }
  
  /** **** messaging ******/
  declare class $npm$firebase$messaging$Messaging {
    deleteToken(token: string): Promise<any>;
    getToken(): Promise<string>;
    onMessage(nextOrObserver: ({}) => void | {}): () => void;
    onTokenRefresh(nextOrObserver: ({}) => void | {}): () => void;
    requestPermission(): Promise<any>;
    setBackgroundMessageHandler(callback: (value: {}) => void): void;
    useServiceWorker(registration: any): void;
  }
  
  /** **** storage ******/
  declare type $npm$firebase$storage$StringFormat =
    | 'raw'
    | 'base64'
    | 'base64url'
    | 'data_url';
  declare type $npm$firebase$storage$TaskEvent = 'state_changed';
  declare type $npm$firebase$storage$TaskState =
    | 'running'
    | 'paused'
    | 'success'
    | 'canceled'
    | 'error';
  
  declare class $npm$firebase$storage$Storage {
    app: $npm$firebase$App;
    maxOperationRetryTime: number;
    maxUploadRetryTime: number;
    ref(path?: string): $npm$firebase$storage$Reference;
    refFromURL(url: string): $npm$firebase$storage$Reference;
    setMaxOperationRetryTime(time: number): void;
    setMaxUploadRetryTime(time: number): void;
  }
  
  declare class $npm$firebase$storage$FullMetadata extends $npm$firebase$storage$UploadMetadata {
    bucket: string;
    downloadURLs: Array<string>;
    fullPath: string;
    generation: string;
    metageneration: string;
    name: string;
    size: number;
    timeCreated: string;
    updated: string;
  }
  
  declare class $npm$firebase$storage$Reference {
    bucket: string;
    fullPath: string;
    name: string;
    parent?: $npm$firebase$storage$Reference;
    root: $npm$firebase$storage$Reference;
    storage: $npm$firebase$storage$Storage;
    child(path: string): $npm$firebase$storage$Reference;
    delete(): Promise<void>;
    getDownloadURL(): Promise<string>;
    getMetadata(): Promise<$npm$firebase$storage$FullMetadata>;
    put(
      data: Blob | Uint8Array | ArrayBuffer,
      metadata?: $npm$firebase$storage$UploadMetadata
    ): $npm$firebase$storage$UploadTask;
    putString(
      data: string,
      format: $npm$firebase$storage$StringFormat,
      metadata?: $npm$firebase$storage$UploadMetadata
    ): $npm$firebase$storage$UploadTask;
    toString(): string;
    updateMetadata(
      metadata: $npm$firebase$storage$SettableMetadata
    ): Promise<$npm$firebase$storage$FullMetadata>;
  }
  
  declare class $npm$firebase$storage$SettableMetadata {
    cacheControl?: string;
    contentDisposition?: string;
    contentEncoding?: string;
    contentLanguage?: string;
    contentType?: string;
    customMetadata?: { [key: string]: string | void };
  }
  
  declare class $npm$firebase$storage$UploadMetadata extends $npm$firebase$storage$SettableMetadata {
    md5Hash?: string;
  }
  
  declare interface $npm$firebase$storage$Observer {
    next: (snapshot: $npm$firebase$storage$UploadTaskSnapshot) => void;
    error?: (error: Error) => void;
    complete?: () => void;
  }
  
  declare type $npm$firebase$storage$Unsubscribe = () => void;
  
  declare type $npm$firebase$storage$Subscribe = (
    observerOrNext: | $npm$firebase$storage$Observer
    | ((snapshot: $npm$firebase$storage$UploadTaskSnapshot) => void),
    onError?: (error: Error) => void,
    onComplete?: () => void
  ) => $npm$firebase$storage$Unsubscribe;
  
  declare class $npm$firebase$storage$UploadTask extends Promise<
    $npm$firebase$storage$UploadTaskSnapshot
  > {
    snapshot: $npm$firebase$storage$UploadTaskSnapshot;
    cancel(): boolean;
    on(
      event: $npm$firebase$storage$TaskEvent,
      ...rest: Array<void>
    ): $npm$firebase$storage$Subscribe;
    on(
      event: $npm$firebase$storage$TaskEvent,
      observerOrNext: | $npm$firebase$storage$Observer
      | ((snapshot: $npm$firebase$storage$UploadTaskSnapshot) => void),
      onError?: (error: Error) => void,
      onComplete?: () => void
    ): $npm$firebase$storage$Unsubscribe;
    pause(): boolean;
    resume(): boolean;
  }
  
  declare class $npm$firebase$storage$UploadTaskSnapshot {
    bytesTransferred: number;
    downloadURL?: string;
    metadata: $npm$firebase$storage$FullMetadata;
    ref: $npm$firebase$storage$Reference;
    state: $npm$firebase$storage$TaskState;
    task: $npm$firebase$storage$UploadTask;
    totalBytes: number;
  }
  
  // Exporting the types
  declare module 'firebase' {
    declare module.exports: {
      +apps: Array<$npm$firebase$App>,
      initializeApp(
        options: $npm$firebase$Config,
        name?: string
      ): $npm$firebase$App,
      SDK_VERSION: string,
      FirebaseError: $npm$firebase$Error,
      FirebaseConfig: $npm$firebase$Config,
      FirebaseUser: typeof $npm$firebase$auth$User,
      FirebaseUserInfo: typeof $npm$firebase$auth$UserInfo,
      app: $Exports<'@firebase/app'>,
      auth: $Exports<'@firebase/auth'>,
      database: $Exports<'@firebase/database'>,
      firestore: $Exports<'@firebase/firestore'>,
      messaging: $Exports<'@firebase/messaging'>,
      storage: $Exports<'@firebase/storage'>
    };
  }
  
  declare module 'firebase/app' {
    declare module.exports: $Exports<'@firebase/app'>;
  }
  
  declare module 'firebase/auth' {
    declare module.exports: $Exports<'@firebase/auth'>
  }
  
  declare module 'firebase/database' {
    declare module.exports: $Exports<'@firebase/database'>;
  }
  
  declare module 'firebase/firestore' {
    declare module.exports: $Exports<'@firebase/firestore'>;
  }
  
  declare module 'firebase/messaging' {
    declare module.exports: $Exports<'@firebase/messaging'>;
  }
  
  declare module '@firebase/app' {
    declare module.exports: {
      (name?: string): $npm$firebase$App,
      App: typeof $npm$firebase$App
    };
  }
  
  declare module '@firebase/auth' {
    declare module.exports: {
      (app?: $npm$firebase$App): $npm$firebase$auth$Auth,
      FirebaseAdditionalUserInfo: $npm$firebase$auth$AdditionalUserInfo,
      FirebaseUserCredential: $npm$firebase$auth$UserCredential,
      ActionCodeInfo: $npm$firebase$auth$ActionCodeInfo,
      ApplicationVerifier: $npm$firebase$auth$ApplicationVerifier,
      Auth: typeof $npm$firebase$auth$Auth,
      AuthCredential: $npm$firebase$auth$AuthCredential,
      AuthProvider: $npm$firebase$auth$AuthProvider,
      ConfirmationResult: $npm$firebase$auth$ConfirmationResult,
      EmailAuthProvider: typeof $npm$firebase$auth$EmailAuthProvider,
      Error: $npm$firebase$auth$Error,
      FacebookAuthProvider: typeof $npm$firebase$auth$FacebookAuthProvider,
      GithubAuthProvider: typeof $npm$firebase$auth$GithubAuthProvider,
      GoogleAuthProvider: typeof $npm$firebase$auth$GoogleAuthProvider,
      PhoneAuthProvider: typeof $npm$firebase$auth$PhoneAuthProvider,
      TwitterAuthProvider: typeof $npm$firebase$auth$TwitterAuthProvider
    };
  }
  
  declare module 'firebase/storage' {
    declare module.exports: $Exports<'firebase/storage'>;
  }
  
  declare module '@firebase/database' {
    declare module.exports: {
      (app?: $npm$firebase$App): $npm$firebase$database$Database,
      enableLogging(
        logger?: boolean | ((msg: string) => void),
        persistent?: boolean
      ): void,
      DataSnapshot: typeof $npm$firebase$database$DataSnapshot,
      Database: typeof $npm$firebase$database$Database,
      OnDisconnect: typeof $npm$firebase$database$OnDisconnect,
      Query: typeof $npm$firebase$database$Query,
      Reference: typeof $npm$firebase$database$Reference,
      ServerValue: typeof $npm$firebase$database$ServerValue,
      ThenableReference: typeof $npm$firebase$database$ThenableReference
    };
  }
  
  declare module '@firebase/firestore' {
    declare module.exports: {
      (app?: $npm$firebase$App): $npm$firebase$firestore$Firestore,
      Blob: $npm$firebase$firestore$Blob,
      CollectionReference: typeof $npm$firebase$firestore$CollectionReference,
      DocumentChange: $npm$firebase$firestore$DocumentChange,
      DocumentReference: typeof $npm$firebase$firestore$DocumentReference,
      DocumentSnapshot: typeof $npm$firebase$firestore$DocumentSnapshot,
      FieldPath: typeof $npm$firebase$firestore$FieldPath,
      FieldValue: $npm$firebase$firestore$FieldValue,
      Firestore: typeof $npm$firebase$firestore$Firestore,
      FirestoreError: $npm$firebase$firestore$FirestoreError,
      GeoPoint: typeof $npm$firebase$firestore$GeoPoint,
      Query: typeof $npm$firebase$firestore$Query,
      QueryListenOptions: $npm$firebase$firestore$QueryListenOptions,
      QuerySnapshot: typeof $npm$firebase$firestore$QuerySnapshot,
      Settings: $npm$firebase$firestore$Settings,
      SnapshotMetadata: $npm$firebase$firestore$SnapshotMetadata,
      Transaction: $npm$firebase$firestore$Transaction,
      WriteBatch: $npm$firebase$firestore$WriteBatch
    };
  }
  
  declare module '@firebase/messaging' {
    declare module.exports: {
      (app?: $npm$firebase$App): $npm$firebase$messaging$Messaging,
      Messaging: $npm$firebase$messaging$Messaging
    };
  }
  
  declare module '@firebase/storage' {
    declare module.exports: {
      (app?: $npm$firebase$App): $npm$firebase$storage$Storage,
      Storage: typeof $npm$firebase$storage$Storage,
      FullMetadata: typeof $npm$firebase$storage$FullMetadata,
      Reference: typeof $npm$firebase$storage$Reference,
      SettableMetadata: typeof $npm$firebase$storage$SettableMetadata,
      UploadMetadata: typeof $npm$firebase$storage$UploadMetadata,
      UploadTask: typeof $npm$firebase$storage$UploadTask,
      UploadTaskSnapshot: typeof $npm$firebase$storage$UploadTaskSnapshot
    };
  }
  