`beforeAuthStateChanged` imported from `@angular/fire/auth` makes `ng build` fail during route extraction

Author: armando-navarroCreated Aug 17, 2026Updated Aug 17, 2026
Labelstype: bugcomp: authcomp: zonescomp: ssr

Description

@angular/fire/auth wraps beforeAuthStateChanged as ɵzoneWrap(_beforeAuthStateChanged, true) (src/auth/firebase.ts line 61). With that flag, the wrapper registers a pending task as soon as a callback is passed and clears it only when the callback first fires or the returned unsubscribe runs (src/zones.ts). This callback only fires when a sign-in or sign-out happens, so an app that registers the hook at startup holds the pending task open and ApplicationRef.isStable never becomes true for a visitor who is not signing in or out.

ng build route extraction waits on app stability, so any server-rendered app that registers this hook in its app config cannot build. Extraction hangs for about 30 seconds, then:

AbortError: Routes extraction was aborted.
TimeoutError: The operation was aborted due to timeout

Steps to reproduce

  1. Fresh ng new --ssr Angular 21 app, ng add @angular/fire@next.
  2. In app.config.ts, register beforeAuthStateChanged inside provideAppInitializer, imported from @angular/fire/auth. Registering it at startup is exactly what an SSR token-cookie sync does (docs/auth.md, Server-side Rendering section).
  3. ng build fails with the error above (34 seconds in my run).
  4. Change only the import to firebase/auth. The identical code builds in under 5 seconds.

Expected behavior

Registering the hook does not permanently block app stability. onMessage in src/messaging/firebase.ts wraps the same shape of API, a callback that may never fire, with the flag set to false, which still zone-wraps the callback and only skips the pending task. The same flag here looks like the fix, pending a check that nothing relies on the blocking behavior. onLog in src/app/firebase.ts has the same shape and is worth sweeping at the same time.

Workarounds in the wild

Our own sample already imports beforeAuthStateChanged from firebase/auth (sample/src/app/auth/auth.component.ts), and the rewritten SSR docs section in #3740 documents that import as the way around this bug.

Versions

Reproduced on an Angular 21 app against the @angular/fire 21 canary. The wrapper is unchanged on current main.