How to Fix Firebase Admin SDK FirebaseAppError: Firebase App named ‘[DEFAULT]’ already exists

Quick Diagnosis

  • ✓ Did you configure the Firebase Admin SDK inside a Next.js App Router route handler or server component?
  • ✓ Does your application execute database queries or auth checks successfully on cold start, but crash with FirebaseAppError on subsequent requests?
  • ✓ Are you invoking initializeApp directly without checking if Sentry-bound or default Firebase instances are already active?

Environment

The Firebase Admin SDK manages database and user authentication lifecycle properties across server configurations including Next.js App Router Route Handlers, Next.js Pages Router API Routes, Serverless Vercel Functions, and Custom Node API Endpoints.

Server Environment State Check Instance Length App Instantiation Command API Verification Status
Cold Start (First Request) getApps().length === 0 initializeApp({ ... }) Success (Instance created)
Warm Start (Subsequent request) getApps().length > 0 (no guard) initializeApp({ ... }) Failed (FirebaseAppError: ‘[DEFAULT]’ already exists)
Warm Start (Subsequent request) getApps().length > 0 (guarded) getApp() Success (Retrieves existing instance)

Minimal Repro

Under serverless execution environments (such as Vercel Functions or AWS Lambda), container instances are kept warm after processing request endpoints to optimize cold-start latencies. When subsequent request endpoints trigger execution, Node.js script contexts are reused without restarting the process lifecycle. The Firebase Admin SDK limits the primary application register context to a single ‘[DEFAULT]’ instance. If your server-side files execute the initializeApp factory constructor directly, subsequent warm-container runs attempt to re-register the ‘[DEFAULT]’ app configuration. Because the app instance is already active in memory, the SDK’s internal registry rejects the duplicate registration, throwing a FirebaseAppError containing the Firebase App named '[DEFAULT]' already exists message. Applying the singleton design pattern resolves this by evaluating getApps().length and reusing the initialized instance.

import { initializeApp, cert } from 'firebase-admin/app';
import { getAuth } from 'firebase-admin/auth';

const serviceAccount = JSON.parse(process.env.FIREBASE_ADMIN_CREDENTIALS);

// CRASH: Directly invoking initializeApp on every route request
const app = initializeApp({
  credential: cert(serviceAccount)
});

export async function GET() {
  const auth = getAuth(app);
  const users = await auth.listUsers();
  return Response.json(users);
}
FirebaseAppError: Firebase App named '[DEFAULT]' already exists. This means you called initializeApp() more than once with the same name.
    at FirebaseAppStore.initializeApp (index.js:52:12)
    at Object.initializeApp (index.js:124:23)

Resolution

When resolving duplicate Firebase instance exceptions, developers can choose between two main structural options depending on their environment complexity.

If you deploy within serverless or Next.js App Router routes, evaluating active app arrays before calling initializers is applicable. This configuration prevents duplicate registration requests.

  1. Import getApps and getApp along with initializeApp.
  2. Evaluate getApps().length to determine if Sentry-bound or default Firebase apps are active.
  3. Re-use the existing instance via getApp() if length is positive.
import { initializeApp, getApps, getApp, cert } from 'firebase-admin/app';
import { getAuth } from 'firebase-admin/auth';

const serviceAccount = JSON.parse(process.env.FIREBASE_ADMIN_CREDENTIALS);

// Guard setup: initialize only if no apps exist
const app = getApps().length > 0 
  ? getApp() 
  : initializeApp({ credential: cert(serviceAccount) });

export const adminAuth = getAuth(app);

Option B: Name Your Firebase Admin App Instances

When you require multiple distinct Firebase connection targets inside the same container scope, supply a unique name argument to initializeApp to avoid default namespace conflicts.

import { initializeApp, cert } from 'firebase-admin/app';

const serviceAccount = JSON.parse(process.env.FIREBASE_ADMIN_CREDENTIALS);

// Specify custom instance namespace
const customApp = initializeApp({
  credential: cert(serviceAccount)
}, 'secondary-tenant');

When This Fix Won’t Work

If the service account credentials JSON string loaded from environment variables is malformed or invalid, initialization calls will throw credential validation errors. Ensure variables match the service account JSON.

Operational Runbook

Case 1: Next.js Routes & Edge Middleware

  1. Import getApps, getApp, and initializeApp inside client config files.
  2. Export client contexts using the guarded singleton checker pattern.

Case 2: Multi-Tenant Environments

  1. Provide dynamic workspace names during initializeApp parameter runs.
  2. Initialize separate auth configurations for distinct workspaces.

Rollback Strategy

To roll back this change, replace the getApps singleton pattern verification conditions with direct initializeApp parameter declarations, delete custom client credentials variables, and revert package configurations to legacy Firebase parameters.


Verification

  • Next.js serverless route handlers complete execution returning HTTP 200 statuses on subsequent warm-container invocations.
  • Server execution logs contain zero FirebaseAppError double-initialization messages.
  • Firebase Admin authentication calls verify credentials and return valid user records.

Error Trigger Point Lifecycle

Parse service account JSON ➔ Check active app instances ➔ Call initializeApp factory [ERROR OCCURS HERE] ➔ Retrieve auth service context ➔ Verify ID tokens ➔ Resolve client requests

References