angular / angular/angularfire

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

Open
#3,748 0 comments 0 reactions 0 assignees View on GitHub
comp: auth comp: ssr comp: zones type: bug
Dominant language
TypeScript
Stars
7.8k
Forks
2.2k
Avg merge
22h 28m
Merged PRs (30d)
6

Description

### 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`.

Contributor guide

Open the contributing guide

Research direction

Reproduce the SSR route-extraction failure with the app configuration described, then inspect src/auth/firebase.ts line 61 and the pending-task behavior in src/zones.ts. Compare the related wrappers in src/messaging/firebase.ts and src/app/firebase.ts, and verify that registering the auth hook no longer prevents ng build from completing.

Written by the indexing model from the issue text.

Assessment

Tech stack
angular, typescript
Domain
authentication, build-system
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.