From 1dbc478c9ab064e3220ea4ac96a4f13648406895 Mon Sep 17 00:00:00 2001 From: Johnny McQuade Date: Thu, 6 Mar 2025 14:37:33 +0000 Subject: [PATCH] fix: firebase auth issues on ios --- .../services/auth/providers/firebase.auth.ts | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/app/shared/services/auth/providers/firebase.auth.ts b/src/app/shared/services/auth/providers/firebase.auth.ts index 36a4b679b..ad8527b37 100644 --- a/src/app/shared/services/auth/providers/firebase.auth.ts +++ b/src/app/shared/services/auth/providers/firebase.auth.ts @@ -1,9 +1,11 @@ import { Injectable, Injector } from "@angular/core"; import { FirebaseAuthentication, User } from "@capacitor-firebase/authentication"; -import { getAuth } from "firebase/auth"; +import { getAuth, initializeAuth, indexedDBLocalPersistence, Auth } from "firebase/auth"; import { FirebaseService } from "../../firebase/firebase.service"; import { AuthProviderBase } from "./base.auth"; import { IAuthUser } from "../types"; +import { FirebaseApp } from "firebase/app"; +import { Capacitor } from "@capacitor/core"; /** LocalStorage field used to store temporary auth profile data */ const AUTH_METADATA_FIELD = "firebase_auth_openid_profile"; @@ -14,12 +16,15 @@ export type FirebaseAuthUser = User; providedIn: "root", }) export class FirebaseAuthProvider extends AuthProviderBase { + private auth: Auth; + public override async initialise(injector: Injector) { const firebaseService = injector.get(FirebaseService); // TODO - is service required here? if (!firebaseService.app) { throw new Error("[Firebase Auth] app not configured"); } + this.initialiseAuth(firebaseService.app); await this.handleAutomatedLogin(); } @@ -43,6 +48,22 @@ export class FirebaseAuthProvider extends AuthProviderBase { return this.authUser(); } + /** + * Configure Firebase Auth to use indexedDB for persistence on native platforms. + * Default mechanism (cookies?) may not be available from capacitor://localhost domains (e.g. on ios) + * See https://stackoverflow.com/a/74904270 + * and https://firebase.google.com/docs/auth/web/custom-dependencies#platform-specific_considerations + */ + private initialiseAuth(app: FirebaseApp) { + if (Capacitor.isNativePlatform()) { + this.auth = initializeAuth(app, { + persistence: indexedDBLocalPersistence, + }); + } else { + this.auth = getAuth(); + } + } + private setAuthUser(user: User, profile: Partial) { const authUser: IAuthUser = { ...profile, @@ -59,7 +80,7 @@ export class FirebaseAuthProvider extends AuthProviderBase { private async handleAutomatedLogin() { // use firebase authStateReady to ensure any previously logged in user is available // and update the auth user with loaded profile - await getAuth().authStateReady(); + await this.auth.authStateReady(); const { user } = await FirebaseAuthentication.getCurrentUser(); if (user) { const storedProfile = localStorage.getItem(AUTH_METADATA_FIELD);