Firebase-admin 不会在 Firebase 上部署的下一个 js 应用上初始化

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

提问人:Juan 提问时间:11/17/2023 最后编辑:Doug StevensonJuan 更新时间:11/17/2023 访问量:32

问:

我正在尝试使用 firebase-tools 的 Web 框架选项将 Next JS 应用程序部署到 Firebase 托管。我遇到的唯一问题是,当我尝试使用它来获取数据或执行任何与之相关的操作时,firebase-admin 似乎从未初始化。 这就是我初始化它的方式,它在本地工作:

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();
}

我如何使用它:

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;
}

当我尝试在firebaseAdminInit.ts文件中记录应用程序时,我看到有一些东西,不是未定义或null值,但是当它在其他地方使用时,它失败说它没有初始化:

FirebaseAppError:默认的 Firebase 应用不存在。确保 在使用任何 Firebase 服务之前调用 initializeApp()。

JavaScript Next.js 托管 Firebase-admin

评论

0赞 Juan 11/18/2023
似乎如果我直接在products.ts文件中调用admin.initializeApp方法,它就可以工作了。我不想在一个大文件中定义需要该应用程序的所有内容。我将尝试依赖注入,并从初始化 firebase 的文件中导出处理逻辑的函数。

答:

0赞 Juan 11/20/2023 #1

似乎如果我尝试通过检查是否已经初始化了应用程序来获取应用程序,或者如果我定义了一个函数来检查我正在处理的环境(开发或生产),我总是会收到错误。 需要像这样初始化才能在 firebase 函数上运行:firebase-admin

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
})

这在本地测试(dev)时会给我带来错误,但它可以在prod上运行,每次我想在本地部署或测试时都必须重写这个代码块,这很烦人。

我使用依赖注入将应用程序传递给所有需要的函数,并且我正在从正在初始化的文件中导出它们,但我还没有尝试通过编写来获取应用程序,这也可能有效。firebase-adminfirebase-adminadmin.app()

我现在也遇到很多错误,每次 firebase 函数都解析请求的正文,以及授权和 cookie 名称的问题,所以如果你想像我一样在 firebase 上部署,我建议其他人等待 Web 框架对下一个 js 的支持变得更好。