From fa10677e41bda50ed88dd9ea9ebfe0d71148fe18 Mon Sep 17 00:00:00 2001 From: Jeet Debnath Date: Thu, 26 Mar 2026 15:05:03 +0530 Subject: [PATCH] fallback sign in flow --- src/contexts/AuthContext.tsx | 24 +++++++++++++++++++++++- src/pages/LoginPage.tsx | 6 +++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/contexts/AuthContext.tsx b/src/contexts/AuthContext.tsx index e9cb473..b748ff3 100644 --- a/src/contexts/AuthContext.tsx +++ b/src/contexts/AuthContext.tsx @@ -10,6 +10,8 @@ import { onAuthStateChanged, setPersistence, signInWithPopup, + signInWithRedirect, + getRedirectResult, signOut as firebaseSignOut, type User, } from 'firebase/auth' @@ -43,6 +45,7 @@ type AuthContextValue = { mongoUser: MongoUser | null loading: boolean secretKey: Uint8Array | null + authError: string | null signInWithGoogle: () => Promise signOut: () => Promise refreshMongoUser: () => Promise @@ -56,6 +59,7 @@ export function AuthProvider({ children }: { children: ReactNode }) { const [mongoUser, setMongoUser] = useState(null) const [secretKey, setSecretKey] = useState(null) const [loading, setLoading] = useState(true) + const [authError, setAuthError] = useState(null) // Initialize encryption keys on login async function initializeEncryption(authUser: User) { @@ -151,6 +155,12 @@ export function AuthProvider({ children }: { children: ReactNode }) { } useEffect(() => { + // Handle returning from a redirect sign-in (mobile flow) + getRedirectResult(auth).catch((error) => { + console.error('[Auth] Redirect sign-in error:', error) + setAuthError(error instanceof Error ? error.message : 'Sign-in failed') + }) + const unsubscribe = onAuthStateChanged(auth, async (u) => { setUser(u) if (u) { @@ -170,8 +180,19 @@ export function AuthProvider({ children }: { children: ReactNode }) { }, []) async function signInWithGoogle() { + setAuthError(null) await setPersistence(auth, browserLocalPersistence) - await signInWithPopup(auth, googleProvider) + try { + await signInWithPopup(auth, googleProvider) + } catch (err: unknown) { + const code = (err as { code?: string })?.code + if (code === 'auth/popup-blocked') { + // Popup was blocked (common on iOS Safari / Android WebViews) — fall back to redirect + await signInWithRedirect(auth, googleProvider) + } else { + throw err + } + } } async function refreshMongoUser() { @@ -205,6 +226,7 @@ export function AuthProvider({ children }: { children: ReactNode }) { mongoUser, secretKey, loading, + authError, signInWithGoogle, signOut, refreshMongoUser, diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx index 5019f78..fe6e551 100644 --- a/src/pages/LoginPage.tsx +++ b/src/pages/LoginPage.tsx @@ -5,7 +5,7 @@ import { GoogleSignInButton } from '../components/GoogleSignInButton' import { TreeAnimation } from '../components/TreeAnimation' export default function LoginPage() { - const { user, loading, signInWithGoogle } = useAuth() + const { user, loading, signInWithGoogle, authError } = useAuth() const navigate = useNavigate() const [signingIn, setSigningIn] = useState(false) const [error, setError] = useState(null) @@ -63,8 +63,8 @@ export default function LoginPage() {

🔒 End-to-end encrypted. We never read your entries.

- {error && ( -

{error}

+ {(error || authError) && ( +

{error || authError}

)}