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 库。
我正在尝试在 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 库。