Skip to content

chore(deps): migrate firebase-admin to v14 (#141) - #142

Merged
spizeck merged 2 commits into
mainfrom
chore/firebase-admin-v14-issue-141
Sep 27, 2026
Merged

spizeck merged 2 commits into
mainfrom
chore/firebase-admin-v14-issue-141

Conversation

@spizeck

@spizeck spizeck commented Sep 27, 2026 •

Copy link
Copy Markdown
Owner

Summary

Migrates firebase-admin ^13.10.0 -> ^14.5.0 and splits the combined lib/firebase-admin.ts helper into per-service modules so Firestore-only routes never import the firebase-admin/auth (jwks-rsa -> jose) dependency graph — the failure class behind the nfl-picks Vercel ERR_REQUIRE_ESM outage. Part of the coordinated fleet migration; follows the proven nfl-picks pattern and the rise-saba migration validated in a real Vercel Preview (spizeck/rise-saba#116).

Closes #141

Changes

  • package.json: firebase-admin -> ^14.5.0; adds check:admin-import script wired into npm test.
  • lib/firebase-admin-app.ts — app initialization (unchanged semantics: env credentials, missing-credential error naming variables).
  • lib/firebase-admin-db.ts — getFirebaseAdminDb (Firestore-only consumers import this alone).
  • lib/firebase-admin-auth.ts — getFirebaseAdminAuth (auth-only consumers import this alone).
  • Deleted lib/firebase-admin.ts; updated all 9 call sites.
  • next.config.ts: adds serverExternalPackages: ["firebase-admin"] — keeps the Admin Node dependency graph out of the serverless bundle.
  • scripts/check-admin-import.mjs — credential-free plain-Node entrypoint import check; asserts installed major is 14.
  • tests/lib/firebase-admin-graph.test.ts — real-dependency-tree regression test (no mocks): entrypoint imports, require("firebase-admin/auth") without ERR_REQUIRE_ESM, source-level guard that Firestore-only modules never import the Auth graph.
  • No jose override yet, deliberately: firebase-admin@14.5.0 resolves jwks-rsa@4.1.0 -> jose@6.1.3 (ESM-only). Whether Vercel's Node 24 runtime tolerates this via require(esm) is verified in this PR's Preview deployment; the scoped jwks-rsa -> jose@5.10.0 override (the nfl-picks fix) will be applied if the failure reproduces.

Verification

  • npm ci / npm install clean (firebase-admin@14.5.0, jwks-rsa@4.1.0, jose@6.1.3 unoverridden)
  • npm run check:react-versions
  • npx tsc --noEmit
  • npm run lint
  • npm test (376 pass incl. new graph suite; check:admin-import prints firebase-admin@14.5.0: server import chain OK)
  • npm run test:rules (needs Java 21+) — no rules changes in this PR
  • npm run build
  • npm run check:md-links
  • Vercel Preview runtime validation (required before merge): GET /api/admin/me without token -> 401 with admin module graph loaded; POST /api/admin/invitations/accept with invalid bearer -> verifyIdToken executes; runtime logs free of ERR_REQUIRE_ESM/jose

Risk / deployment notes

  • No secrets, credentials, or private data were committed.

  • Preview-only validation; no production deployment. If the Preview runtime reproduces ERR_REQUIRE_ESM, the scoped jose@5.10.0 override gets added and redeployed before merge.

Summary by Sourcery

Upgrade Firebase Admin to v14 and isolate its service dependency graphs to ensure reliable server-side imports.

Bug Fixes:

  • Prevent Firebase Admin dependency loading failures caused by the Auth graph’s ESM-only jose dependency in server runtimes.

Enhancements:

  • Split Firebase Admin app, Auth, and Firestore access into separate modules so Firestore-only consumers avoid importing the Auth dependency graph.
  • Externalize firebase-admin from Next.js server bundles and add runtime dependency checks for the Firebase Admin 14 import chain.

Build:

  • Upgrade firebase-admin to version 14.5.0 and pin jwks-rsa’s jose dependency to a require-compatible 5.x release.

Tests:

  • Add real-dependency import and module-graph regression tests covering Firebase Admin versioning, Auth loading, jose resolution, and Firestore-only imports.

Chores:

  • Update all Firebase Admin consumers to use the new service-specific modules.

…es (#141)

firebase-admin 14 removes the legacy namespace API — this repo already
used modular entrypoints. The real change is architectural: the combined
lib/firebase-admin.ts is split into firebase-admin-app/-db/-auth modules
so Firestore-only routes (trade leads, audit, user/invitation records)
no longer import firebase-admin/auth — whose jwks-rsa -> jose chain is
the class of failure behind the nfl-picks Vercel ERR_REQUIRE_ESM outage.

serverExternalPackages keeps firebase-admin out of the server bundle so
Next does not rewrite its Node-specific dependency graph. A plain-Node
import smoke check (npm run check:admin-import, wired into npm test) and
a module-graph regression test guard the split and the runtime chain.

The jose override is intentionally NOT applied yet: whether Vercel's
Node 24 runtime tolerates jose@6 via require(esm) is verified in the
Preview deployment for this PR (issue #141 tracks the checklist).

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @spizeck, this account has used its review budget of 1,500,000 diff characters for the last 7 days.

You can request another review in 1 day and 1 hour by commenting @sourcery-ai review. Upgrade to get a review now.

@vercel

vercel Bot commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
deepdivebrewing-web Ready Ready Preview Sep 27, 2026 11:00pm UTC

Request Review

@sourcery-ai

sourcery-ai Bot commented Sep 27, 2026

Copy link
Copy Markdown

Reviewer's Guide

Migrates firebase-admin to v14 while isolating Auth from Firestore imports, externalizing the Admin package from Next.js server bundles, and adding dependency-tree regression checks aimed at preventing ERR_REQUIRE_ESM failures. Review the module boundaries and route import updates, the serverExternalPackages behavior, and the remaining required Vercel Preview runtime validation before merge.

Sequence diagram for credential-free Firebase Admin import validation

sequenceDiagram
    participant Check as check-admin-import.mjs
    participant Node as Node runtime
    participant Package as firebase-admin@14
    participant App as firebase-admin/app
    participant Auth as firebase-admin/auth
    participant Firestore as firebase-admin/firestore

    Check->>Node: findPackageJSON(firebase-admin)
    Node-->>Check: package version
    Check->>Check: [version starts with 14.]
    Check->>Package: import firebase-admin/app
    Package-->>Check: initializeApp, cert, getApps
    Check->>Package: import firebase-admin/auth
    Package-->>Check: getAuth
    Check->>Package: import firebase-admin/firestore
    Package-->>Check: getFirestore
    Check->>Node: console.log(server import chain OK)
Loading

Flow diagram for Firestore-only dependency isolation

flowchart TD
    Route[Firestore-only route or library]
    DB[getFirebaseAdminDb]
    App[getFirebaseAdminApp]
    Firestore[firebase-admin/firestore]
    AuthGraph[firebase-admin/auth\njwks-rsa -> jose]

    Route --> DB
    DB --> App
    DB --> Firestore
    DB -. does not import .-> AuthGraph
Loading

File-Level Changes

Change Details Files
Split Firebase Admin initialization and service access into isolated modules to prevent Firestore-only code from importing the Auth dependency graph.
  • Moved shared app initialization into a dedicated module while preserving credential handling and error behavior.
  • Added separate Firestore and Auth helpers.
  • Updated all Firebase Admin consumers and removed the combined helper.
lib/firebase-admin-app.ts
lib/firebase-admin-auth.ts
lib/firebase-admin-db.ts
lib/firebase-admin.ts
app/api/admin/bootstrap/route.ts
app/api/admin/invitations/[id]/resend/route.ts
app/api/admin/invitations/accept/route.ts
app/api/admin/users/[uid]/route.ts
lib/admin-audit.ts
lib/admin-auth.ts
lib/admin-invitations.ts
lib/admin-users.ts
lib/trade-leads.ts
Upgrade firebase-admin to v14 and configure Next.js to load the Node dependency graph externally at runtime.
  • Bumped firebase-admin from ^13.10.0 to ^14.5.0 and regenerated the lockfile.
  • Added firebase-admin to serverExternalPackages.
package.json
package-lock.json
next.config.ts
Add runtime and regression checks for the Firebase Admin dependency graph and the required v14 installation.
  • Added a plain-Node import smoke check for Admin app, Auth, and Firestore entrypoints.
  • Wired the smoke check into npm test.
  • Added real-dependency tests for v14 resolution, require-based Auth loading, entrypoint imports, and Firestore-only source isolation.
scripts/check-admin-import.mjs
tests/lib/firebase-admin-graph.test.ts
package.json

Assessment against linked issues

Issue Objective Addressed Explanation
#141 Migrate firebase-admin to ^14.5.0 and isolate the Firebase Admin app, Firestore, and Auth modules so Firestore-only code does not import the Auth dependency graph; configure Next.js to externalize firebase-admin. ✅
#141 Add credential-free plain-Node import validation and module-graph regression coverage, and wire the import smoke check into the test workflow. ✅
#141 Deploy a Vercel Preview, exercise an Admin Auth route in the deployed runtime, inspect logs for ERR_REQUIRE_ESM/jose failures, and apply and document the scoped jose override if the runtime failure occurs. ❌ The PR explicitly leaves Vercel Preview runtime validation unchecked and states that the jose override will only be added if a failure reproduces. The code changes and local tests do not verify the deployed Vercel runtime or provide the required runtime outcome/documentation.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

The Preview deployment reproduced the exact outage class: firebase-admin
-> jwks-rsa (CJS) requires jose; unoverridden resolution picks jose@6.1.3
(ESM-only), and Vercel's externalized module loader rejects the ESM
require even on Node 24 — both admin API routes 500'd at module load.

Scoped override (matches the proven nfl-picks fix): jwks-rsa -> jose
5.10.0. Resolution now firebase-admin@14.5.0 -> jwks-rsa@4.1.0 ->
jose@5.10.0. The graph regression test now asserts jose stays require-able.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@spizeck

spizeck commented Sep 27, 2026

Copy link
Copy Markdown
Owner Author

Vercel Preview runtime validation — PASSED (after jose pin)

Two-stage result — the failure reproduced exactly as predicted without the pin:

Deploy dpl_75Ybwqh2VgqJwxFWig1sjNzKG5A8 (commit 16e14ed, NO jose override, jose@6.1.3 resolved):

  • GET /api/admin/me -> 500; POST /api/admin/invitations/accept -> 500
  • Runtime logs: Error [ERR_REQUIRE_ESM]: require() of ES Module jose/dist/webapi/index.js from jwks-rsa/src/utils.js — the exact nfl-picks outage class, reproduced on Node 24 even with serverExternalPackages. The override is still required on Admin 14.5.0.

Deploy dpl_5bFbQjDW1eXpL1XeN5rNmVH71tdb (commit d95d509, scoped jwks-rsa -> jose@5.10.0 override):

  • GET /api/admin/me -> 401 {"ok":false,"error":"Missing bearer token."} — expected app response
  • POST /api/admin/invitations/accept (invalid bearer) -> 401 {"ok":false,"error":"Invalid or expired ID token."} — verifyIdToken() executed the full auth graph in the serverless runtime
  • get_runtime_errors scoped to this deployment: zero errors

Resolved tree: firebase-admin@14.5.0 -> jwks-rsa@4.1.0 -> jose@5.10.0. Remaining CI (Verify job) still running at time of comment.

@spizeck

spizeck commented Sep 27, 2026

Copy link
Copy Markdown
Owner Author

Verified that it works in preview.

@spizeck
spizeck merged commit 8d3359b into main Sep 27, 2026
4 checks passed
@spizeck
spizeck deleted the chore/firebase-admin-v14-issue-141 branch September 27, 2026 23:28

This branch was successfully deployed

1 active deployment
Preview — d95d5099 Deployed Sep 27, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Maintenance: migrate Firebase Admin to v14 with Vercel runtime validation

1 participant