Is there an existing issue for this?
Which plugins are affected?
Auth
Which platforms are affected?
Web
Description
Bug description
On Flutter web, Firebase.initializeApp() intermittently never completes, leaving the app on a permanently blank page. A manual browser reload recovers it. The browser console shows a Firebase JS SDK auth error originating in IndexedDBLocalPersistence._openDb, thrown during the initial user restoration:
IndexedDB can be transiently unavailable at page load (a browser storage race, private-mode restrictions, or third‑party storage partitioning when the serving origin differs from authDomain). When that happens, the JS SDK's initialization promise rejects and the first onAuthStateChanged callback fires with an error instead of a user.
Root cause
firebase_auth_web waits for the first auth-state event during plugin registration, via Auth.onWaitInitState() in packages/firebase_auth/firebase_auth_web/lib/src/interop/auth.dart (unchanged on master as of this writing):
Future<void> onWaitInitState() async {
final completer = Completer();
final nextWrapper = (auth_interop.UserJsImpl? user) {
_initUser = User.getInstance(user);
completer.complete();
};
final errorWrapper = (JSAny e) => _changeController!.addError(e);
final unsubscribe =
jsObject.onAuthStateChanged(nextWrapper.toJS, errorWrapper.toJS);
await completer.future;
unsubscribe.callAsFunction();
}
On the error path there are two defects:
-
The completer is never completed on error. errorWrapper routes the error to _changeController and never calls completer.complete()/completeError(), so await completer.future waits forever.
-
_changeController is null at this point. During registerWith the onAuthStateChanged stream getter has not been accessed yet, so _changeController is null and _changeController!.addError(e) throws a null-check error inside the JS callback — the error is not surfaced to Dart at all.
onWaitInitState() is awaited inside FirebaseAuthWeb.registerWith (firebase_auth_web.dart, await authDelegate.onWaitInitState();), which is awaited during Firebase.initializeApp(). Because the completer never completes, Firebase.initializeApp() never returns, runApp is never reached, and the page stays blank. A reload creates a fresh JS Auth instance that (outside the unavailability window) succeeds, which is why reloading "fixes" it.
Note: this is distinct from the graceful "persistence not supported" fallback. getAuthInstance passes the persistence hierarchy [indexedDBLocalPersistence, browserLocalPersistence, browserSessionPersistence], which handles unsupported stores, but a hard runtime _openDb rejection surfaces as an init error that onWaitInitState mishandles rather than falling through.
Reproducing the issue
Steps to reproduce
- Flutter web app that awaits
Firebase.initializeApp() before runApp, using default (IndexedDB-backed) auth persistence.
- Force IndexedDB
open to fail/reject at page load (e.g. run in a context where IndexedDB is momentarily unavailable, block site data, or stub indexedDB.open to reject). This mimics the intermittent real-world failure.
- Load the app.
Firebase Core version
4.15.0
Flutter Version
3.47.4 / Dart: 3.13+
Relevant Log Output
at IndexedDBLocalPersistence._openDb (indexed_db.ts:252:5)
at IndexedDBLocalPersistence._withRetries (indexed_db.ts:270:18)
at IndexedDBLocalPersistence._withPendingWrite (indexed_db.ts:403:14)
at IndexedDBLocalPersistence._set (indexed_db.ts:405:18)
at PersistenceUserManager.setCurrentUser (persistence_user_manager.ts:69:3)
at AuthImpl.directlySetCurrentUser (auth_impl.ts:797:18)
at AuthImpl.reloadAndSetCurrentUserOrClear (auth_impl.ts:398:3)
at async auth_impl.ts:191:12
Flutter dependencies
Expand Flutter dependencies snippet
Replace this line with the contents of your `flutter pub deps -- --style=compact`.
Additional context and comments
No response
Is there an existing issue for this?
Which plugins are affected?
Auth
Which platforms are affected?
Web
Description
Bug description
On Flutter web,
Firebase.initializeApp()intermittently never completes, leaving the app on a permanently blank page. A manual browser reload recovers it. The browser console shows a Firebase JS SDK auth error originating inIndexedDBLocalPersistence._openDb, thrown during the initial user restoration:IndexedDB can be transiently unavailable at page load (a browser storage race, private-mode restrictions, or third‑party storage partitioning when the serving origin differs from
authDomain). When that happens, the JS SDK's initialization promise rejects and the firstonAuthStateChangedcallback fires with an error instead of a user.Root cause
firebase_auth_webwaits for the first auth-state event during plugin registration, viaAuth.onWaitInitState()inpackages/firebase_auth/firebase_auth_web/lib/src/interop/auth.dart(unchanged onmasteras of this writing):On the error path there are two defects:
The completer is never completed on error.
errorWrapperroutes the error to_changeControllerand never callscompleter.complete()/completeError(), soawait completer.futurewaits forever._changeControlleris null at this point. DuringregisterWiththeonAuthStateChangedstream getter has not been accessed yet, so_changeControlleris null and_changeController!.addError(e)throws a null-check error inside the JS callback — the error is not surfaced to Dart at all.onWaitInitState()is awaited insideFirebaseAuthWeb.registerWith(firebase_auth_web.dart,await authDelegate.onWaitInitState();), which is awaited duringFirebase.initializeApp(). Because the completer never completes,Firebase.initializeApp()never returns,runAppis never reached, and the page stays blank. A reload creates a fresh JS Auth instance that (outside the unavailability window) succeeds, which is why reloading "fixes" it.Note: this is distinct from the graceful "persistence not supported" fallback.
getAuthInstancepasses the persistence hierarchy[indexedDBLocalPersistence, browserLocalPersistence, browserSessionPersistence], which handles unsupported stores, but a hard runtime_openDbrejection surfaces as an init error thatonWaitInitStatemishandles rather than falling through.Reproducing the issue
Steps to reproduce
Firebase.initializeApp()beforerunApp, using default (IndexedDB-backed) auth persistence.opento fail/reject at page load (e.g. run in a context where IndexedDB is momentarily unavailable, block site data, or stubindexedDB.opento reject). This mimics the intermittent real-world failure.Firebase Core version
4.15.0
Flutter Version
3.47.4 / Dart: 3.13+
Relevant Log Output
Flutter dependencies
Expand
Flutter dependenciessnippetReplace this line with the contents of your `flutter pub deps -- --style=compact`.Additional context and comments
No response