The Firebase Auth bug that took me 3 days to find (it wasn't Firebase's fault)

The Firebase Auth bug that took me 3 days to find (it wasn't Firebase's fault)

Leader 1 2 9
calendar_today agoschedule2 min read

The symptom

signInWithRedirect would fire fine — the Google popup flow completed, the redirect came back, and then... nothing. auth.currentUser was null. No error in the console. No failed network request. The user object had just vanished somewhere between the redirect and my app reading it.

The frustrating part: it worked perfectly on localhost. It only broke in production.

The wrong turns

First guess: async timing bug. I wrapped the auth-state check in every useEffect variation I could think of, added loading states, tried onAuthStateChanged instead of reading currentUser directly. No change.

Second guess: a config mismatch. I diffed my Firebase config between local and prod character by character. Identical.

Third guess: CORS. Checked network tab, no CORS errors, no failed requests at all — which in hindsight should have been the clue. A CORS problem fails loudly. This was failing silently.

What was actually happening

Firebase's redirect-based auth flow works by briefly using an iframe on your authDomain (typically your-project.firebaseapp.com) to relay the session back to your app. That relay depends on third-party storage being accessible inside that iframe — cookies/localStorage set on firebaseapp.com, read while your actual site is on a different domain.

Browsers have been steadily tightening third-party storage partitioning (Safari's been strict about this for years, Chrome's been catching up). Production was on my real custom domain. Local dev was hitting localhost, which a lot of browsers still treat more permissively. That's why it "worked" locally and silently died in prod — the iframe's storage access was just being partitioned away, and Firebase had no clean way to surface that as an error since, from its perspective, the browser just... didn't return anything.

The fix

Switch to signInWithPopup instead of signInWithRedirect. Popup-based auth doesn't rely on that same cross-domain iframe storage relay — the popup and the opener communicate directly, sidestepping the whole partitioning problem.

// Before: silently broke in production
await signInWithRedirect(auth, provider);

// After: works consistently across browsers
await signInWithPopup(auth, provider);

Trade-off: popups get blocked more aggressively on mobile and by some ad blockers, so it's not a strictly-better default — just a better fit for what was actually failing here.

The lesson

When something works locally and silently fails in production with zero error output, my new first suspect is cross-origin storage behavior, not application logic. Silent failure is often the browser deciding not to tell you it blocked something, rather than your code doing something wrong.

Anyone else hit this exact wall with Firebase (or any auth provider using a similar iframe-relay pattern)? Curious if others landed on popup, or found a way to keep redirect working reliably.

🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

How I Built a React Portfolio in 7 Days That Landed ₹1.2L in Freelance Work

Dharanidharan - Feb 9

I’m a Senior Dev and I’ve Forgotten How to Think Without a Prompt

Karol Modelski - Mar 19

TypeScript Complexity Has Finally Reached the Point of Total Absurdity

Karol Modelski - Apr 23

Sovereign Intelligence: The Complete 25,000 Word Blueprint (Download)

Pocket Portfolio - Apr 1

5 Web Dev Pitfalls That Are Silently Killing Your Projects (With Real Fixes)

Dharanidharan - Mar 3
chevron_left
780 Points12 Badges
3Posts
2Comments
8Connections
Solo dev building CircuitForge (free 3D circuit simulator at luvaai.in). Wrestling with Three.js, React 19, and simulation math.

Related Jobs

Commenters (This Week)

9 comments
3 comments
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!