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

问题描述 投票:0回答:2

我正在尝试使用 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 文件中时,我看到有一些东西,不是未定义或空值,但是当它在其他地方使用时,它会失败,提示它未初始化:

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

javascript firebase next.js firebase-hosting firebase-admin
2个回答
0
投票

似乎如果我尝试通过检查是否有已初始化的应用程序来获取应用程序,或者如果我定义一个函数检查我正在处理的环境(开发或生产),我总是会收到错误。

firebase-admin
需要 像这样初始化才能在 firebase 函数上运行:

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

这会在本地测试(开发)时给我带来错误,但它会在产品上工作,这很烦人,每次我想在本地部署或测试时都必须重写这段代码。

我使用依赖注入将应用程序传递给所有需要

firebase-admin
的函数,并且我从正在初始化
firebase-admin
的文件中导出它们,但我还没有尝试通过编写
admin.app()
来获取应用程序,这也可能有效。

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


0
投票

当我尝试在 Next.js API 路由(在服务器中运行)中使用 firebase-admin 时,我遇到了同样的问题。您的解决方法帮助我们找出问题所在。直接调用 admin.app() 或 getApp() 会导致 firebase 函数出错。而是使用 getApps()[0]。我不知道原因。

使用下面的代码,我成功从 API 路由(在服务器中运行)导入

adminAuth
adminFirestore

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);
© www.soinside.com 2019 - 2024. All rights reserved.