Skip to content

chore(sample): update the sample app to Angular 22 - #3845

Draft
armando-navarro wants to merge 1 commit into
angular:mainfrom
armando-navarro:sample-angular-22
Draft

armando-navarro wants to merge 1 commit into
angular:mainfrom
armando-navarro:sample-angular-22

Conversation

@armando-navarro

Copy link
Copy Markdown
Collaborator

Checklist

  • Issue number for this PR: Refs modernize the sample app #3669, Refs One call to build the right Firebase app for server rendering #3843
  • Docs included?: the sample's own README.md is updated. No library docs change.
  • Test units included?: yes, the sample's two spec files (4 tests). app.component.spec.ts is updated for the new providers and name.
  • Breaking change?: no. The library is untouched.
  • In a clean directory, yarn install, yarn test run successfully?: yes, with npm, inside sample/ on Node 24: npm install ../angular-fire-22.0.0.tgz, ng build, ng test (2 files, 4 tests).

Description

Carries sample/ from Angular 21 to Angular 22, the way #3671 carried it from 19 to 21:

  • ng update @angular/core@22 @angular/cli@22
  • Hand edits that match what ng new 22 generates
  • AngularFire library installed from the tarball the root build produces.
  • It also moves the sample's server-rendering setup to initializeBrowserOrServerApp from feat(app): add initializeBrowserOrServerApp for browser & server apps #3844, which replaces the hand-written server-app factory and releases the server app the old factory never released.

Changes

  • @angular/* 22.2, TypeScript 6.0, firebase 13, vitest 5, jsdom 30, @types/node 22, the ng22-test name, and Node 24 (firebase 13's packages require it).

  • app.config.ts matches the 22 scaffold:

    • provideBrowserGlobalErrorListeners() added
    • provideZonelessChangeDetection() dropped (zoneless is the default)
    • provideClientHydration() without withIncrementalHydration() (incremental hydration is the default).
    • The spec drops the same two providers.
  • Removed ChangeDetectionStrategy.Eager that Angular's change-detection-eager migration added to all nine components again (so it does not appear in the diff), and the sample runs on Angular 22's OnPush default.

  • app.config.ts: one provideFirebaseApp(() => initializeBrowserOrServerApp(environment.firebase)) for both platforms, as step 4 of the Authentication guide shows.

    • In the browser the helper returns the ordinary Firebase app.
    • On the server it reads the ID token from the request context that server.ts already passes to handle(), builds a Firebase server app for a signed-in render and the ordinary app otherwise, and releases the server app once the render is garbage-collected.
    • app.config.client.ts is deleted. Its browser-only providers (Analytics with the two tracking services, Messaging, Performance) move to app.config.ts, since each already provides nothing on the server, and main.ts bootstraps from appConfig, as ng new does. app.config.server.ts keeps only provideServerRendering.
  • Calls to functions AngularFire does not wrap (doc, collection, query, orderBy, increment, serverTimestamp) sit outside runInInjectionContext, with a one-line comment on each.

    • Only the wrapped functions, sign-in and sign-out calls run inside it.
    • GoogleAuthProvider, onIdTokenChanged and signInWithPopup are imported from @angular/fire/auth.
    • onAuthStateChanged stays the SDK's own inside the sample's authState, which applies the wrapper to the whole function.
  • server.ts keeps the trustProxyHeaders: ['x-forwarded-host', 'x-forwarded-proto'] the trust-proxy-headers migration wrote, with a comment in place of its TODO.

  • angular.json: security.allowedHosts gains localhost.

    • Angular 22 gives a 400 Bad Request error to any host not on that list (Angular 21 logged an error and fell back to client-side rendering), and it was empty, so npm run serve:ssr:ng22-test could not be reached locally.
    • README.md has a "Running the server build" section that says deployments add their hostnames there or in NG_ALLOWED_HOSTS.
  • tsconfig.app.json keeps the extendedDiagnostics block the strict-safe-navigation-narrow migration wrote.

  • functions/package.json moves to the Node 24 runtime. Both package-lock.json files regenerated with npm 10.

Behavior to know

  • The sample now needs Node 24.15 or later. On Node 22 the install prints EBADENGINE warnings for the firebase packages.

Verification

  • ng build and ng test (2 files, 4 tests) on Node 24.22.2, with one copy of firebase (npm ls firebase).
  • Emulator session (firebase emulators:exec --import seed with the production server bundle):
    • signed-out server render with the eight demos in the HTML, anonymous sign-in, an upboat write, the Cloud Function call, sign-out, then a signed-in server render whose HTML carries the uid.
    • No AngularFire warning or error in the browser console or the server log.
  • The same under ng serve, where AngularFire's injection-context warning prints: sign-in, a write and the function call with no AngularFire warning.
    • The hydration log reports the seven @defer blocks on incremental hydration.
  • npm run build of the Cloud Function from its regenerated lockfile.

Not exercised: "New animal" (a window.prompt), "Log in with Google" (a real provider popup), Messaging (no token flow in the emulators).

Carries sample/ from Angular 21 to 22 with ng update, matching what
ng new 22 generates: TypeScript 6, firebase 13, vitest 5, Node 24,
provideBrowserGlobalErrorListeners, no explicit zoneless provider
and no withIncrementalHydration (both are defaults now), the Eager
change detection the migration adds removed again so the components
run on the OnPush default.

The server app is now built by initializeBrowserOrServerApp, which
reads the ID token from the request context and releases the server
app after the render. The old factory never released it.

Calls to functions AngularFire does not wrap sit outside
runInInjectionContext, with a comment on each, so the sample shows
where the injection context is needed and where it is not.

security.allowedHosts gains localhost: Angular 22 answers 400 to
any host not on the list, so the built server could not be run
locally. Both lockfiles regenerated with npm 10.

Refs angular#3669
@armando-navarro armando-navarro added comp: other Doesn't clearly map to a module or cross-cutting area. type: chore Maintenance with no user-facing behavior change. labels Nov 11, 2026
@armando-navarro armando-navarro added this to the 22.0.0-rc.1 milestone Nov 11, 2026
armando-navarro added a commit to armando-navarro/angularfire that referenced this pull request Nov 11, 2026
The sample app now has one provideFirebaseApp with
initializeBrowserOrServerApp in its shared app.config.ts (angular#3845), so
the sentence about its split client and server files no longer holds.

Refs angular#3843
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp: other Doesn't clearly map to a module or cross-cutting area. type: chore Maintenance with no user-facing behavior change.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant