Estoy tratando de probar una pequeña aplicación de muestra Ionic/Angular en un emulador de iOS.
En la web, todas las solicitudes de firestore usando angularfire funcionan perfectamente bien.
De alguna manera, si trato de ejecutar la misma aplicación en el emulador, sigue cargando la respuesta de la solicitud (si fuera una respuesta vacía, diría que no se pudieron recuperar los resultados).
Que esta pasando? ¿Necesito configurar algo específicamente para que el emulador funcione y realice solicitudes a 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 }; Luego, en su componente, llame a su método como este await signInAnonymously(auth); . No olvide importar la auth que exportamos en la parte superior.
He estado luchando mucho con este problema también, pero logré solucionarlo. Para aquellos que necesitan ayuda aquí está mi código.
Puede eliminar todas las importaciones relacionadas con Firebase de app.module.ts ya que esta solución solo usa Firebase. Los paquetes rxfire y @angular/fire se pueden eliminar de su package.json . La única dependencia que tengo es "firebase": "^9.6.1" . Usé observables para las funciones getObject y list ya que es a lo que estoy acostumbrado y no quería volver a escribir mi código original.
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(); } }; }); } }Para aquellos que no pueden ver el mensaje de error lanzado por firebase, pruebe el siguiente comando en su consola Safari para ver el error.
window.location.reload()El problema real: firebase-js-sdk en iOS móvil asume que la API de Google (gapi) existe en la ventana, incluso cuando no se usa.
Encontré una solución alternativa: Mock window.gapi antes de usar el inicio de sesión de autenticación de firebase:
window['gapi'] = { load: (name: string) => Promise.resolve(), iframes: { getContext: () => { return { iframe: { contentWindow: { postMessage: (message: any) => { console.log("gapi iframe message:", message); } } } } } } } as any;