Skip to content

Commit 8c85d9f

Browse files
author
MStarRobotics
committed
fix(auth): ensure Google sign-in popup works reliably across browsers by preloading GIS script on app mount
- Export preloadGoogleIdentity() and call it on App mount - Retain lazy-load as fallback but avoid losing user gesture - No UI or type changes; safe and cross-browser friendly
1 parent 73b8034 commit 8c85d9f

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed

App.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { generateRecipe, generateImageForRecipe } from './services/geminiService
99
import { LANGUAGES, COOKING_TIMES, DISH_TYPES, RECIPE_GENERATION_MESSAGES, IMAGE_GENERATION_MESSAGES } from './constants';
1010
import { connectWallet, recordRecipeOnchain, fetchOnchainCookbook, resolveBasename, fetchMembershipPrice, checkLifetimeMembership, purchaseLifetimeMembership, DEFAULT_MEMBERSHIP_PRICE_WEI } from './services/baseRegistry';
1111
import { clearPersistedToken, fetchAuthenticatedProfile, isMetaMaskAvailable, linkWalletToGoogleAccount, persistAuthToken, requestNonce, retrievePersistedToken, signMessageWithWallet, verifySignature, logout as logoutSession } from './services/authService';
12+
import { preloadGoogleIdentity } from './services/googleIdentity';
1213
import type { User } from 'firebase/auth';
1314
import { firebaseSignOut, isFirebaseReady, signInWithFirebaseCustomToken, signInWithGooglePopup, subscribeToFirebaseAuth } from './services/firebaseClient';
1415
import type { GoogleIdentityProfile } from './services/googleIdentity';
@@ -358,6 +359,10 @@ const App: React.FC = () => {
358359
}, []);
359360

360361
React.useEffect(() => {
362+
// Preload Google Identity script early so the click handler can open the
363+
// consent popup within the same user gesture (prevents popup blockers).
364+
void preloadGoogleIdentity();
365+
361366
detectProviderAvailability();
362367
const globalWindow =
363368
typeof globalThis === 'object' &&

services/googleIdentity.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,19 @@ const loadGoogleIdentityScript = async (): Promise<void> => {
5454
return scriptPromise;
5555
};
5656

57+
// Preload the Google Identity Services script early so that any popup/consent UI
58+
// can be triggered within a direct user gesture (click) without being blocked
59+
// by browsers like Safari/Chrome. Exported for callers (e.g., App) to invoke on mount.
60+
export const preloadGoogleIdentity = async (): Promise<void> => {
61+
try {
62+
await loadGoogleIdentityScript();
63+
} catch (err) {
64+
// Swallow preload errors; a subsequent interactive call will surface a clearer message
65+
// and we don't want this to break app startup.
66+
console.warn('Google Identity script preload failed:', err);
67+
}
68+
};
69+
5770
export type GoogleIdentityProfile = {
5871
googleId: string;
5972
email?: string;
@@ -100,6 +113,10 @@ export const signInWithGoogleIdentity = async (): Promise<GoogleIdentityProfile>
100113
throw new Error('Set VITE_GOOGLE_OAUTH_CLIENT_ID to enable Google sign-in.');
101114
}
102115

116+
// The script is expected to be preloaded during app initialization to retain
117+
// the user gesture context for the popup. We still attempt a quick load here
118+
// in case preload was skipped, but note some browsers may block the popup if
119+
// this lazy load occurs after the click.
103120
await loadGoogleIdentityScript();
104121

105122
return new Promise<GoogleIdentityProfile>((resolve, reject) => {

0 commit comments

Comments
 (0)