Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase-admin won't initialize on a next js app deployed on Firebase

I'm trying to deploy a Next JS app to Firebase hosting using the web framework option firebase-tools has. The only issue I've encoutered is that firebase-admin seems to never initialize when I try to use it to fetch data, or do anything related with it. This is how I'm initializing it, it works locally:

firebase/firebaseAdminInit.ts

import admin from 'firebase-admin';

export function GetFirebaseAdminApp() {
    if(admin.apps.length === 0){
        const app = admin.initializeApp({
            credential:admin.credential.cert({
                clientEmail: process.env.NEXT_FIREBASE_CLIENT_EMAIL as string,
                projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID as string,
                privateKey: process.env.NEXT_FIREBASE_PRIVATE_KEY as string
            }),
            databaseURL: process.env.NEXT_PUBLIC_FIREBASE_DATABASE_URL as string,
            storageBucket: process.env.NEXT_PUBLIC_STORAGE_BUCKET as string
        });
        return app;
    }
    return admin.app();
}

How I use it:

lib/repository/products.ts

import { getFirelord, getFirestore, getDocs, query, orderBy, limit, offset, getCountFromServer, addDoc, updateDoc, getDoc, deleteDoc } from "firelord";
import { ProductsMetaType } from "./dtoModels";
import { Product, ProductRequest, productToDomain, productType_toDto } from "../domain/Products";
import { GetFirebaseAdminApp } from "../../firebase/firebaseAdminInit";
import { PagedQuery, PagedResult } from "../domain/PagedQueries";
import formidable from "formidable";
import { DeleteImage, UploadImage } from "./objectStorage";

const app = getFirestore(GetFirebaseAdminApp()); //This should return the firebase-admin app
const productFl = getFirelord<ProductsMetaType>(app, 'Products');

export async function GetAllProducts() {
    const docs =
        await getDocs(productFl.collection()).then(qSnapshot =>
            qSnapshot.docs.map(docSnapshot => docSnapshot.data())
        ).then(dtoArr => dtoArr.map(productToDomain))
    return docs;
}

When I try to log the app in the firebaseAdminInit.ts file I see that there's something, not a undefined or null value, but when it gets used somewhere else it fails saying it's not initialized:

FirebaseAppError: The default Firebase app does not exist. Make sure you call initializeApp() before using any of the Firebase services.

like image 597
Juan Avatar asked Sep 06 '25 03:09

Juan


1 Answers

I ran into the same issue when I was trying to use firebase-admin in Next.js API Routes (run in server). Your workaround helped we figuring out what was the issue. Calling directly admin.app() or getApp() will cause error in firebase functions. Instead use getApps()[0]. I do not know the reason.

With the code below, I imported succesfully adminAuth and adminFirestore from API Routes (run in server).

lib/firebase-admin.ts

import { AppOptions, cert, getApps, initializeApp, ServiceAccount } from "firebase-admin/app";
import { getAuth } from "firebase-admin/auth";
import { getFirestore } from "firebase-admin/firestore";

const credentials: ServiceAccount = {
  projectId: process.env.FIREBASE_ADMIN_SDK_FIREBASE_PROJECT_ID,
  privateKey: process.env.FIREBASE_ADMIN_SDK_PRIVATE_KEY?.replace(/\\n/g, "\n"),
  clientEmail: process.env.FIREBASE_ADMIN_SDK_CLIENT_EMAIL,
};

const options: AppOptions = {
  credential: cert(credentials),
};

export const initializeFirebaseAdmin = () => {
  const firebaseAdminApps = getApps();
  if (firebaseAdminApps.length > 0) {
    return firebaseAdminApps[0];
  }

  return initializeApp(options);
}

const firebaseAdmin = initializeFirebaseAdmin();

export const adminAuth = getAuth(firebaseAdmin);
export const adminFirestore = getFirestore(firebaseAdmin);
like image 78
emarazz Avatar answered Sep 07 '25 21:09

emarazz