fix(admin): resolve the [DEFAULT] Firebase app instead of the first-registered app - #131
Merged
fwal merged 3 commits intoSep 19, 2026
Conversation
|
fwal
reviewed
Sep 19, 2026
fwal
approved these changes
Sep 19, 2026
fwal
deleted the
detail/bug-fix/fix-admin-resolve-the-default-firebase-app-instead-4fabd3
branch
September 19, 2026 13:58
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Detail bug report: View on Detail
Closes #112
Bug
Admin.layer()(no args) auto-resolved the Firebase admin app withoptions.app || getApps()[0] || initializeApp().getApps()[0]returns thefirst-registered app (Map insertion order), not the
[DEFAULT]app — so when anamed/non-default app is registered before (or instead of) the default,
FirestoreServicegets bound to that app's project/credentials and all Firestore reads/writes/streams go to
the wrong Firebase project. The
initializeApp()fallback was also short-circuitedwhenever any app existed.
This silently breaks in two real cases: the documented multi-project pattern (named
secondary app registered first), and
firebase-functionsv2 cold-start auto-initializingthe named
__FIREBASE_FUNCTIONS_SDK__app before the user'sinitializeApp()runs. In thecommon single-default-app deployment
getApps()[0] === getApp()and the bug is masked.The docstring labeled step 3 as the "existing default app" and step 4 as "a newly
initialized default app" — confirming the intent was always the
[DEFAULT]app, whichcontradicts the
getApps()[0]implementation. The siblingClient.layeralready resolvesvia
getApp(), so admin was inconsistent.Fix
Resolve the app through a
resolveApphelper that mirrorsClient.layer, replacinggetApps()[0]with the canonical default-app accessorgetApp()(which throws when nodefault exists) and falling back to
initializeApp()on throw:Import changed from
getApps→getApp; docstring updated so step 3 readsgetApp().Testing
admin.spec.ts(the first test forAdmin.layer): usesvi.mockwithimportOriginal(the repo's established pattern) to controlgetApp/getApps/initializeApp/getFirestoreand asserts which app reachesgetFirestore(app)— the same end-to-end seam the bug inspects. Covers the explicit-apppath, the
[DEFAULT]selection when a named app is registered first, theinitializeApp()fallback when only a named (or no) app exists, the
{ firestore }short-circuit, and theboth-args throw. Confirmed bug-sensitive: reverting to the buggy line makes the
default-selection and fallback tests fail.
firebase-adminapp store (onlygetFirestoreproxied to avoid credentials): a named app registered before[DEFAULT]→ fix binds
[DEFAULT](buggy binds the named app);firebase-functionsSDK auto-initof
__FIREBASE_FUNCTIONS_SDK__→ fix binds a fresh[DEFAULT]loaded fromFIREBASE_CONFIG; multi-project smoke → explicit{ app }targets the named project,no-arg targets the default.
nx run-many -t build, the full admin suite (9 files / 76 tests), eslint,prettier, and
nx affected -t lint test buildall pass.firebase.json/.firebasercandfirebase loginrequires interactive browser OAuththat can't be completed headlessly. The deployment cold-start scenario was instead
reproduced locally with the real
firebase-functionsSDK auto-init.Automatic Fixes PRs can be configured here.