Repository navigation
feat: accept firebase 13 alongside firebase 12 - #3831
Conversation
firebase 13.1.0 is npm latest, so `npm install firebase` followed by `ng add @angular/fire@22` failed with ERESOLVE against the ^12.18.0 peer. The peer range is now ^12.18.0 || ^13.0.0, and rxfire moves to ^6.3.0, whose peer range includes firebase 13. The ng add and ng update schematics now write the range of the firebase major already installed. ng add installs the missing peer at the newest allowed version before the schematic runs, so writing ^12.18.0 over an installed 13 left two @firebase/app copies and the app failed at startup. The lookup walks up to a monorepo root, and an installed copy the app's own entry excludes is ignored. The package keeps building against firebase 12, the oldest supported major, because the generated wrappers import functions by name from the installed firebase. A new CI job runs the specs against firebase 13.1.0 on Node 24, which firebase 13 requires. Fixes angular#3830
…ecursive option Node 26 removed the recursive option of fs.rmdirSync, so the spec failed in the Node 26 CI jobs. Delete the files and directories one by one instead, as duplicatePackages.jasmine.ts already does.
tyler-reitz
left a comment
There was a problem hiding this comment.
One blocking point: the monorepo spec's cleanup throws on Node 26, which is what fails all three Test Node 26 jobs.
rmdirSync(repository, { recursive: true }) is rejected there with The property 'options.recursive' is no longer supported; Node 24 only warns (DEP0147). Locally on Node 26, test:node reports 401 specs, 1 failure, "finds firebase installed at a monorepo root above the workspace", and the temp directory is left behind. The same tree on Node 24 passes 401/401. With @types/node at 12.12.41 there's no typed rmSync, so either a types bump or a cast; your call.
On the installed-version lookup you asked about: it reads _backend._root the same way setup/index.ts does, and walking up matches how Node resolves the package. Neutering the walk-up, the installed-version read, and the excluded-copy guard each turns its spec red, so the coverage holds. The one thing I'd note is that the walk-up has no stopping point: with no in-tree firebase and no firebase entry, a stray copy in an ancestor such as ~/node_modules decides the range. Node would resolve that same copy at runtime, so I read it as low risk (inferred, not run).
Everything else checked out, including the firebase 13 job and both browser suites.
|
Thanks, Tyler. The Node 26 failure is fixed in 5c5a8b9. I went with neither a types bump nor a cast: the spec now deletes its temporary directory file by file, the way That also removes the DEP0147 warning the old cleanup printed on Node 22 and 24. Locally, On the walk-up, I agree it's low risk, so I've left it as is. It only reaches above the app when the app's own Could you take another look? |
tyler-reitz
left a comment
There was a problem hiding this comment.
Approving. The removeDirectory helper fixes the Node 26 failure: all three Test Node 26 jobs pass on 5c5a8b9, along with the firebase 13 job and both browser suites.
angular#3831 lets AngularFire 22 accept firebase 12 or 13, and the ng update migration now writes the range of the firebase major already installed. The upgrade guide still said the migration writes ^12.18.0 and quoted peer warnings that name only that range. State the supported range and what the migration writes, update the Yarn 1 and pnpm 9/10 warnings to their current wording, and add a section on moving to firebase 13: VertexAIBackend is removed and its packages declare Node 24.12 or later. Refs angular#3830
* docs: say which wrapped calls do not hold the app unstable docs/zones.md says callback APIs hold the app unstable until an initial value, so a server render waits for data. #3827 makes a set of calls exceptions because their first callback may never come. Waiting on a callback that never comes would keep the app from ever becoming stable. List those calls in docs/zones.md, and point at onValue, object, list, listVal and fromRef with the value event as the calls that still make a server render wait. In docs/database.md, say the same under stateChanges, auditTrail and fromRef. Refs #3826 * docs: describe firebase 13 support in the v22 upgrade guide #3831 lets AngularFire 22 accept firebase 12 or 13, and the ng update migration now writes the range of the firebase major already installed. The upgrade guide still said the migration writes ^12.18.0 and quoted peer warnings that name only that range. State the supported range and what the migration writes, update the Yarn 1 and pnpm 9/10 warnings to their current wording, and add a section on moving to firebase 13: VertexAIBackend is removed and its packages declare Node 24.12 or later. Refs #3830 * docs: describe microtask delivery in the v22 upgrade guide #3833 moves every Observable read from a setInterval timer to the next microtask checkpoint. As a breaking change it needs a section in the upgrade guide: which tests now see a value they used to wait for, the setTimeout ordering flip, and the zoneless server render case for hand-written TransferState entries. Refs #3832 * docs: describe the callback pending-task change in the v22 upgrade guide #3837 removes a callback read's pending task right after the callback instead of one setTimeout(fn, 0) delay later. As a breaking change it needs a section in the upgrade guide: what moves sooner, and which tests notice. Refs #3836 * docs: say a handler passed as an observer object is wrapped too #3829 wraps a handler passed as an observer object, such as { next, error }, the way it wraps a function, so the injection context reaches both forms. Refs #3828 * docs(compat): add a setup section in NgModule and standalone form The compat API's setup steps left docs/install-and-setup.md when #3236 rewrote it for the modular API, and nothing replaced them. docs/compat.md had no setup at all, the Realtime Database pages pointed at an "Installation guide" that no longer covered compat, and no page showed the standalone form. A standalone app with only the modular providers then fails its first compat injection with NG0201 for angularfire2.app.options (#3683). The new section on docs/compat.md gives both forms, says when the modular providers may stay, states the error the missing module produces, and lists the compat module of each product. The twelve compat pages that had an NgModule-only snippet or no setup at all now point at it. Fixes #3683 * docs: say which package managers refuse an incompatible firebase The v22 upgrade guide said an incompatible firebase is refused at install time. Only npm refuses it, and only when package.json requests the incompatible version. Yarn and pnpm install it with a warning. * docs: say which Firestore functions are not zone wrapped #3842 re-exports Firestore's query and reference builders, field values, comparators and setLogLevel without the zone wrapper. In docs/zones.md, add a paragraph listing them, change the switchMap example to a read, since building the query no longer warns, and say the Verbose log level covers only wrapped calls. Refs #3842 * docs(auth): build the server app with initializeBrowserOrServerApp The server-rendering guide's step 4 becomes the one call, the five details become three, the App Check token gets a relay section, the response gets a Cache-Control header, and the manual callback stays in a "Building the app yourself" section that step 4 points at, for apps that prefer it or whose AngularFire version has no such function. The release modes say what a throwing ngOnDestroy does to a timed release. * docs(auth): describe the sample as an example of the one-call server app The sample app now has one provideFirebaseApp with initializeBrowserOrServerApp in its shared app.config.ts (#3845), so the sentence about its split client and server files no longer holds. Refs #3843 * docs: say how to move from 22.0.0-rc.0 in the v22 upgrade guide The guide covered upgrades from 21, a 21 release candidate and a 22 canary build, but not from the first 22 release candidate. ng add saves a prerelease as an exact version, so an app on 22.0.0-rc.0 stays there until ng update @angular/fire@next moves it. That command also runs migration-v22 again, which reports "No changes made" for a firebase entry already inside the supported range. Refs #3834 * docs(auth): say which hooks stop a releaseAfterRender release The caveat on releaseAfterRender said a throwing ngOnDestroy "stops that teardown". It now says the release is a DestroyRef.onDestroy callback, that Angular runs it after every service's and component's ngOnDestroy, and that an ngOnDestroy method or an ApplicationRef.onDestroy listener that throws keeps it from running. The default release, which does not run during the injector's destroy, is unaffected either way. A new paragraph says to call initializeBrowserOrServerApp in app.config.ts rather than a route's providers: a route's child injector is not destroyed with the request, so a release registered there never runs. Refs #3844 * docs(auth): say the default release still happens from a route's providers Tyler asked on #3844 whether the default release, now tied to a root service, releases a server app built in a lazy route's providers. It does: the request's root injector is destroyed, the route's child injector is not, so only a releaseAfterRender release registered there is lost. Checked with a child environment injector that is never destroyed, in both modes. Refs #3844 * docs: add onConfigUpdate to the calls that do not hold the app unstable #3829 set onConfigUpdate to blockUntilFirst: false in tools/build.ts, because its observer runs only when a fetched template differs from the active one. The list in docs/zones.md left it out. Found in the #3835 review. Refs #3829 * docs(auth): say a second provideFirebaseApp can render signed out The bullet said a second registration makes a signed-in render fail on a freshly started server. With more than one registration, FirebaseApp resolves to the default app. Run on fresh servers, a second plain initializeApp(config) registration creates that app on the first request, so signed-in pages render signed out with no error. Only when no registration creates the default app, as with two initializeBrowserOrServerApp registrations, does the render fail, and only until a signed-out request creates it. Found in the #3835 review. Refs #3844
Fixes #3830
docs/version-22-upgrade.mdchanges go on the single rc.1 docs pull request, which merges just before the tag.src/schematics/common.jasmine.ts.yarn install,yarn testrun successfully? yes, with npm:npm ci,npm run build,npm run lint,npm run test:nodeandnpm run test:chrome-headless.Description
This lets
@angular/fire22 accept firebase 13 alongside 12, song addstops failing withERESOLVEon apps that already have firebase 13. The reasoning is in the linked issue.Changes
src/package.json:firebaseis^12.18.0 || ^13.0.0.rxfireis^6.3.0.alignFirebaseVersioninsrc/schematics/common.ts, used byng addand the v21 and v22 migrations:^12.18.0 || ^13.0.0alone.node_modules/firebasein the workspace and then in each parent directory, so it also finds a monorepo root install.^13.0.0, and anything else gets^12.18.0..github/workflows/test.ymlhas a new "Test firebase 13" job:test:nodeandtest:chrome-headlesson Node 24, with firebase 13.1.0 installed over the firebase 12 build.test_and_contributeandpublishboth wait on it.Behavior to know
ng add @angular/fireon a new app with no firebase now writes^13.0.0, because npm has already installed firebase 13 as the missing peer.^12.18.0, so the app stays on 12.node_modules/firebase, so a new app on pnpm gets^12.18.0and one copy of firebase 12.idFieldonto the object a Firestore converter returns, instead of onto a copy.idFieldset, a converter that returns a frozen object now throws incollectionDataanddocData.^6.2.0already resolves to 6.3.0.Verified outside CI
ng addin fresh Angular 22 apps ended with one copy of firebase in every starting state I tried: no firebase, firebase 12 or 13 already installed, and entries like>=13.0.0,*and a firebase 13 prerelease.ng updatefrom Angular 21 to 22 kept each app on its existing firebase major.Tyler, the part I'd most like a second look at is the installed-version lookup in
alignFirebaseVersion, since it reads outside the schematic tree.