Node.js 中的 Firebase Admin SDK 全局应用初始化

Sam*_*itt 10 node.js firebase firebase-realtime-database firebase-admin

我正在构建一个 Express.js 应用,使用 Firebase Admin SDK 实现 ID 令牌验证和 Cloud Firestore 访问等多项功能。在我的主 app.js 文件中,我将应用程序初始化为:

const admin = require('firebase-admin')

const serviceAccount = require('../config/account-credentials.json')
admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: 'https://databaseurl.firebaseio.com'
})
Run Code Online (Sandbox Code Playgroud)

在另一个文件中,我所做的就是导入:

const admin = require('firebase-admin')
Run Code Online (Sandbox Code Playgroud)

我可以admin.auth().verifyIdToken很好地调用和验证 ID 令牌。但是,当我致电时app.database(),它抱怨该应用程序从未初始化。再次初始化应用程序会产生一个新错误:

默认 Firebase 应用已存在。这意味着您多次调用了initializeApp(),而没有提供应用程序名称作为第二个参数。在大多数情况下,您只需要调用一次initializeApp()。但如果您确实想初始化多个应用程序,请将第二个参数传递给initializeApp(),以便为每个应用程序指定一个唯一的名称。

我是否需要创建多个具有不同名称的应用程序才能正常工作?或者我如何在整个项目中使用一个应用程序。

Jas*_*rne 11

您应该只初始化一次应用程序,然后重新使用该引用。有多种方法可以做到这一点,但我更喜欢的方法是将firebase.ts(初始化 Firebase 应用程序和服务)导入到我的index.ts(或任何您的入口点)中。然后我传递对需要特定服务的任何其他文件的引用。我使用的是 TypeScript,因此如果您使用的是普通 JS,请根据需要进行调整。

firebase.ts

import * as admin from 'firebase-admin';

// Initialize our project application
admin.initializeApp();

// Set up database connection
const firestoreDb: FirebaseFirestore.Firestore = admin.firestore();
firestoreDb.settings({ timestampsInSnapshots: true });
export const db = firestoreDb;
Run Code Online (Sandbox Code Playgroud)

我的 index.ts 文件将导入它:

import { db } from './firebase';
Run Code Online (Sandbox Code Playgroud)

然后,当我使用 Express 设置路线时,我会将每条路线放在另一个文件中,并具有其自己的功能。然后将数据库引用传递给任何需要它的人。

  app
    .route('events')
    .get((req: Request, res: Response) => {
      get_events(db, res);
      return;
    });
Run Code Online (Sandbox Code Playgroud)

这是一篇博客文章,我对此进行了更多解释:

https://medium.com/@jasonbyrne/how-to-struct-a-serverless-rest-api-with-firebase-functions-express-1d7b93aaa6af

如果您不喜欢依赖注入方法或者更喜欢仅延迟加载您需要的服务,您可以采用另一种不同的方式。在该方法中,您可以将firebase.js文件(或您所说的任何名称)导入到任何需要它的页面,并调用函数来加载该服务。这里我只是做 Firestore,但是您可以创建类似的函数来引用其他服务。

只是将其作为示例输入...

import * as admin from 'firebase-admin';

// Initialize our project application
admin.initializeApp();

// Database reference, not yet loaded
let db: FirebaseFirestore.Firestore | null = null;

// Get cached db reference or create it
export function getDatabaseReference() {
    if (db === null) {
        db = admin.firestore();
    }
    return db;
}
Run Code Online (Sandbox Code Playgroud)

我希望这有帮助。如果您有任何疑问,请告诉我。