Angular / Ionic 移动应用 ios 不使用 angularfire 从 Firebase 获取

Angular / Ionic mobile app ios does not fetch from Firebase using angularfire

我正在尝试在 iOS 模拟器上测试一些 Ionic/Angular 示例应用程序。

在网络上,使用 angularfire 对 firestore 的所有请求都工作得很好。

不知何故,如果我尝试在模拟器上执行相同的应用程序,它会不断加载请求的响应(如果它是一个空响应,它会说无法检索到任何结果)。

这是怎么回事?我是否需要专门为 Emulator 设置一些内容才能工作并执行对 Firestore 的请求?

import { initializeApp } from 'firebase/app';
import { getFirestore } from 'firebase/firestore';
import { Capacitor } from '@capacitor/core';
import { initializeAuth, indexedDBLocalPersistence } from 'firebase/auth';
import { getAuth } from 'firebase/auth';

const firebaseApp = initializeApp({
 apiKey: process.env.VUE_APP_FIREBASE_API_KEY,
 authDomain: process.env.VUE_APP_FIREBASE_AUTH_DOMAIN,
 databaseURL: process.env.VUE_APP_FIREBASE_DATABASE_URL,
 projectId: process.env.VUE_APP_FIREBASE_PROJECT_ID,
 storageBucket: process.env.VUE_APP_FIREBASE_STORAGE_BUCKET,
 messagingSenderId: 
 process.env.VUE_APP_FIREBASE_MESSAGING_SENDER_ID,
 appId: process.env.VUE_APP_FIREBASE_APP_ID,
});


function whichAuth() {
  let auth
  if (Capacitor.isNativePlatform()) {
    auth = initializeAuth(firebaseApp, {
      persistence: indexedDBLocalPersistence
    })
  } else {
    auth = getAuth()
  }
  return auth
}

export const auth = whichAuth()
const db = getFirestore();

export const auth = whichAuth();
export { firebaseApp, db };

然后在您的组件中,像这样 await signInAnonymously(auth); 调用您的方法。不要忘记导入我们在顶部导出的 auth

我也为这个问题苦苦挣扎,但我设法解决了它。对于那些需要帮助的人,这是我的代码。

您可以从 app.module.ts 中删除所有与 Firebase 相关的导入,因为此解决方案仅使用 Firebase。 包 rxfire@angular/fire 可以从您的 package.json 中删除。我唯一的依赖是 "firebase": "^9.6.1"。 我对 getObject 和 list 函数使用了 observables,因为这是我习惯的,我不想重写我的原始代码。

import { Injectable } from '@angular/core';
import { Capacitor } from '@capacitor/core';
import { environment } from '@environment';
import { initializeApp } from 'firebase/app';
import { Auth, getAuth, indexedDBLocalPersistence, initializeAuth, signInWithCustomToken } from 'firebase/auth';
import { Database, getDatabase, onValue, orderByChild, query, ref } from 'firebase/database';
import { Observable, Observer, from } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class FirebaseService {
  private readonly database: Database;
  private readonly auth: Auth;

  constructor() {
    const firebaseApp = initializeApp(environment.firebase);

    if (Capacitor.isNativePlatform()) {
      initializeAuth(firebaseApp, {
        persistence: indexedDBLocalPersistence
      });
    }

    this.database = getDatabase(firebaseApp);
    this.auth = getAuth(firebaseApp);
  }

  connectFirebase(firebaseToken) {
    return from(signInWithCustomToken(this.auth, firebaseToken));
  }

  disconnectFirebase() {
    return from(this.auth.signOut());
  }

  getObject<T>(path: string): Observable<T> {
    return new Observable((observer: Observer<T>) => {
      const dbRef = ref(this.database, path);
      const listener = onValue(dbRef, snapshot => {
        const data = snapshot.val();
        observer.next(data);
      });

      return {
        unsubscribe() {
          listener();
        }
      };
    });
  }

  public list<T>(path: string, orderChildBy?: string): Observable<Array<T>> {
    return new Observable<Array<T>>((observer: Observer<Array<T>>) => {
      const dbRef = ref(this.database, path);
      const dbReference = !orderChildBy ? dbRef : query(dbRef, orderByChild(orderChildBy));

      const listener = onValue(dbReference, snapshot => {
        const data = Object.values<T>(snapshot.val() || {});
        console.log(path, data);
        observer.next(data);
      });

      return {
        unsubscribe() {
          listener();
        }
      };
    });
  }
}

对于那些看不到 firebase 抛出的错误消息的人,请在您的 Safari 控制台中尝试以下命令以查看错误。

window.location.reload()

真正的问题:firebase-js-sdk 在手机上 iOS 假定 google API (gapi) 存在于 window 上,即使它不存在用过。

我找到了解决方法:在使用 firebase 身份验证登录之前模拟 window.gapi:

window['gapi'] = {
  load: (name: string) => Promise.resolve(),
  iframes: {
    getContext: () => {
      return {
        iframe: {
          contentWindow: {
            postMessage: (message: any) => {
              console.log("gapi iframe message:", message);
            }
          }
        }
      }
    }
  }
} as any;

TL;DR:capacitor.config 中设置 server: { iosScheme: "ionic" }

问题似乎是 Firebase 错误地检测了环境(请参阅@alistairheath 的 comment here)。

auth/compat library here which checks for the URL scheme "ionic://", which was used by older versions of Capacitor (it's now "capacitor://") and if you set it back to "ionic://" (see the config option iosScheme) 中进行了检查,它似乎再次工作并且不会尝试加载 gapi 库。