Skip to content

Commit a560be1

Browse files
committed
feat(auth): fallback to redirect when popup login fails
1 parent c0debf2 commit a560be1

1 file changed

Lines changed: 48 additions & 2 deletions

File tree

src/firebase.ts

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { initializeApp } from 'firebase/app';
2-
import { getAuth, GoogleAuthProvider, signInWithPopup, signOut } from 'firebase/auth';
2+
import { AuthError, getAuth, GoogleAuthProvider, signInWithPopup, signInWithRedirect, signOut } from 'firebase/auth';
33
import { getFirestore } from 'firebase/firestore';
44
import firebaseConfig from '../firebase-applet-config.json';
55

@@ -8,7 +8,53 @@ export const db = getFirestore(app, firebaseConfig.firestoreDatabaseId);
88
export const auth = getAuth(app);
99
export const googleProvider = new GoogleAuthProvider();
1010

11-
export const loginWithGoogle = () => signInWithPopup(auth, googleProvider);
11+
const REDIRECT_ELIGIBLE_POPUP_ERROR_CODES: ReadonlySet<string> = new Set([
12+
'auth/popup-blocked',
13+
'auth/popup-closed-by-user',
14+
'auth/cancelled-popup-request',
15+
'auth/operation-not-supported-in-this-environment',
16+
]);
17+
18+
function isAuthError(error: unknown): error is AuthError {
19+
if (!error || typeof error !== 'object') {
20+
return false;
21+
}
22+
23+
const candidate = error as Partial<AuthError>;
24+
return typeof candidate.code === 'string';
25+
}
26+
27+
function shouldFallbackToRedirect(error: AuthError): boolean {
28+
return REDIRECT_ELIGIBLE_POPUP_ERROR_CODES.has(error.code);
29+
}
30+
31+
export const loginWithGoogle = async (): Promise<void> => {
32+
try {
33+
await signInWithPopup(auth, googleProvider);
34+
} catch (error) {
35+
if (isAuthError(error) && shouldFallbackToRedirect(error)) {
36+
// COOP/preview-related popup constraints can be non-fatal; redirect login remains valid.
37+
console.warn('google_login_popup_failed_redirect_fallback', {
38+
code: error.code,
39+
message: error.message,
40+
});
41+
await signInWithRedirect(auth, googleProvider);
42+
return;
43+
}
44+
45+
if (isAuthError(error)) {
46+
console.error('google_login_failed', {
47+
code: error.code,
48+
message: error.message,
49+
});
50+
throw error;
51+
}
52+
53+
console.error('google_login_failed_unknown_error', { error });
54+
throw error;
55+
}
56+
};
57+
1258
export const logout = () => signOut(auth);
1359

1460
export enum OperationType {

0 commit comments

Comments
 (0)