Firebase Auth login succeeded but session was lost on every page refresh after moving to a custom domain. Root cause: the custom domain was not added to Firebase Console's Authorized Domains list for the Authentication project. Session cookies and token refresh calls require the domain to be explicitly authorized.
Resolution Steps
During TrustSeal's custom domain activation (March 2026), Firebase Auth appeared to work — users could log in through the email/password flow and the app showed the authenticated state. But refreshing the page immediately showed the login screen again. The session was not persisting.
The error only appeared in the browser DevTools console under the Network tab — a failed POST to https://identitytoolkit.googleapis.com/v1/accounts:lookup?key=... returned a 400 with UNAUTHORIZED_DOMAIN in the response body. The Firebase Auth SDK caught this silently and treated it as a sign-out event.
Before the custom domain was configured, all development and testing was done on localhost (which Firebase automatically includes in the authorized list) and the github.io subdomain. Neither revealed the issue because both were already authorized.
Firebase Auth uses a combination of:
The token refresh call includes the origin header of the requesting domain. Firebase validates this against the Authorized Domains list. If the domain is not listed, the refresh is rejected, the token expires, and Firebase Auth fires the onAuthStateChanged callback with null — which the app interprets as "user logged out."
The login itself can complete because the login form's POST request origin may still be validated against localhost or the GitHub Pages domain. But the refresh fails the moment the custom domain tries to issue one.
Firebase Auth's Authorized Domains list is not automatically updated when a custom domain is configured on GitHub Pages, Vercel, or any other hosting provider. It is a separate Firebase Console configuration step that must be done explicitly.
Default authorized domains (always present):
localhost[project-id].firebaseapp.com[project-id].web.appMust be added manually:
[username].github.io)Firebase Console → Authentication → Settings → Authorized Domains → Add Domain
Added trustseal.asquaresolution.com. No code changes, no redeploy — the setting takes effect server-side immediately.
For ScamCheck (scamcheck.asquaresolution.com), the same configuration was added during initial setup after learning from the TrustSeal incident. Both custom domains and the GitHub Pages testing subdomain were added before going live.
Pre-launch checklist for any Firebase Auth deployment with custom domains:
Pattern: This is a silent configuration failure — the app works completely in development and test environments, then fails in a specific production context (the custom domain) with no visible error in the UI. Same class as environment-variable-missing-production and Razorpay key mode mismatch: a credential or authorization that is scoped to one context is absent from another.
Fix Confidence
Recovery Complexity
Pattern Family
This failure belongs to a named recurring pattern. Other failures in this family share the same root cause structure — understanding the pattern prevents multiple failure types simultaneously.
Related Failures in Same Pattern
Prevention Lessons
Completing these lessons would have prevented this failure.
Demonstrated In
This failure occurred in a real production context. These case studies show the full arc from incident to resolution.