修复由于多个firebase初始化导致的Firebase错误

时间:2018-02-08 13:04:04

标签: node.js firebase

我正在开发一个使用 firebase 作为数据库的应用。我们在后端(基于Node Express构建的REST API)上使用firebase-admin仅用于需要管理员权限的操作,例如用户身份验证,用户帐户删除等。我们假设我们有一个端点,如:

app.post('/auth/user/signin', function(req, res){
    const ev = req.body;
    const email = ev.email;
    const password = ev.password;

    firebaseAdmin.initializeApp({
      credential: {some admin creds}),
      databaseURL: {some database URL}
    });

    return someFirebaseAuthQuery()
     .then(() => {

        // Some auth related code
        ...
        ...
        ...

        firebaseAdmin.auth().app.delete();
        return res.
           status(some status).
           json(some data);
     })
});

我们遇到的问题是,当两个用户同时签署请求时,firebaseAdmin.initializeApp()会被调用两次(每个用户一次),这会引发一个错误,指出 Firebase App已经存在。知道如何解决这个问题吗?

3 个答案:

答案 0 :(得分:3)

每次收到请求时都不应创建实例。如果您正在运行快速应用程序,这不是正确的方法。虽然如果您在云端功能上托管您的应用程序,那么它将运行良好。

此处的错误是您尝试使用相同的名称初始化firebaze管理应用程序两次,这是"默认"

如果你能看到带有两个参数的initializeApp的定义,而你只给出一个参数,那么它将采用"默认"默认为名称。

initializeApp(options, name) returns admin.app.App

所以实现这一目标的最佳方法是在Express应用程序启动时创建一个文件来初始化admin应用程序并导出该实例并在您需要的时候在您的应用程序中使用它

<强> firebaseConfig.js

const admin = require('firebase-admin');
const serviceAccount = require('../serviceAccountKey.json');

admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'https://xxxxxxxxxxxx.firebaseio.com',
});

module.exports.admin = admin

并在您的路线处理文件中

<强> example.js

const { admin } = require('./firebaseConfig.js');

app.post('/auth/user/signin', function(req, res){
    const ev = req.body;
    const email = ev.email;
    const password = ev.password;

    return someFirebaseAuthQuery()
    .then(() => {

        // Some auth related code
        ...
        ...
        ...
        // do not need to delete app
        return res.
        status(some status).
        json(some data);
    })
});

或者如果您想继续使用您的流程,请提供一些唯一标识符来初始化应用程序,如下所示。

firebaseAdmin.initializeApp({
  credential: {some admin creds}),
  databaseURL: {some database URL}
}, "UNIQUE_IDENTIFIER");

但后来不会因为非常明显的原因而受到鼓励

我希望这能解决您的问题

答案 1 :(得分:1)

firebase只需要初始化一次。因此,应用程序初始化时应调​​用firebaseAdmin.initializeApp一次。它应该在app.post

之外

答案 2 :(得分:0)

这是在Node.js上使用firebase-admin管理多个应用的​​方法

const admin = require('firebase-admin');
const service1 = require('./app1-service.json');
const service2 = require('./app2-service.json');

const apps = {
  app1: null,
  app2: null,
};

void init() {
  // check and init app1
  const initialisedApps = admin.apps.map((item) => item.name);
  if (!initialisedApps.includes('app1')) {
    apps.app1 = admin.initializeApp({
      credential: admin.credential.cert(service1),
    }, 'app1');
  } else apps.app1 = admin.app('app1');
  
  // check and init app2
  if (!initialisedApps.includes('app2')) {
    apps.app2 = admin.initializeApp({
      credential: admin.credential.cert(service2),
    }, 'app2');
  } else apps.app2 = admin.app('app2');
}