如何修复由于React SSR初始化数据库和云功能firebase初始化数据库导致的Firebase数据库多次初始化?

Sub*_*ndu 5 javascript node.js firebase google-cloud-functions

我已经更新了问题,找到了问题的根本原因。当我托管了我的React SSR应用程序时,该应用程序在客户端中使用Firebase数据库,该客户端通过名为的云函数之一app抛出错误Error: FIREBASE FATAL ERROR: Database initialized multiple times. Please make sure the format of the database URL matches with each database() call.。当我逐一注释并部署时,效果很好。但是当我一起部署时不起作用。如何将这两个保持在相同的仓库中分开?

原始问题:Why firebase cloud function throwing an error of 'The default Firebase app does not exist.'? 所以我第一次尝试使用firebase函数。admin.messaging()向我抛出以下错误。帮我弄清楚为什么吗?如果我看一下控制台,我会得到结果,直到console.log('deviceToken', deviceToken);

那么const messageDone = await admin.messaging().sendToDevice(deviceToken, payload);怎么了?

const functions = require('firebase-functions');
const admin = require('firebase-admin');
exports.updateUnreadCount = functions.database.ref('/chats/{chatId}/{messageId}')
  .onCreate(async(snap, context) => {
    const appOptions = JSON.parse(process.env.FIREBASE_CONFIG);
    appOptions.databaseAuthVariableOverride = context.auth;
    const adminApp = admin.initializeApp(appOptions, 'app');
    const { message, senderId, receiverUid } = snap.val();
    console.log(message, senderId, receiverUid);
    console.log('------------------------');
    const deleteApp = () => adminApp.delete().catch(() => null);
    try {
      const db = adminApp.database();
      const reciverUserRef = await db.ref(`users/${receiverUid}/contacts/${senderId}/`);
      console.log('reciverUserRef', reciverUserRef);
      const deviceTokenSnapshot = await reciverUserRef.child('deviceToken').once('value');
      const deviceToken = await deviceTokenSnapshot.val();
      console.log('deviceToken', deviceToken);

      const payload = {
        notification: {
          title: 'Test Notification Title',
          body: message,
          sound: 'default',
          badge: '1'
        }
      };
      const messageDone = await admin.messaging().sendToDevice(deviceToken, payload);
      console.log('Successfully sent message: ', JSON.stringify(messageDone));
      return deleteApp().then(() => res);
    } catch (err) {
      console.log('error', err);
      return deleteApp().then(() => Promise.reject(err));
    }
  });
Run Code Online (Sandbox Code Playgroud)

UPDATE1:这一https://firebase.google.com/docs/cloud-messaging/send-message#send_to_a_topicadmin.messaging().sendToDevice(deviceToken, payload)API是只可在管理Node.js的SDK?所以切换到

const payload = {
        data: {
          title: 'Test Notification Title',
          body: message,
          sound: 'default',
          badge: '1'
        },
        token: deviceToken
      };
      const messageDone = await admin.messaging().send(payload);
Run Code Online (Sandbox Code Playgroud)

这也不起作用。遇到错误Error: The default Firebase app does not exist. Make sure you call initializeApp() before using any of the Firebase services.任何线索都将有所帮助。

编辑:终于使功能正常工作。我的index.js正在导出为函数,

exports.app = functions.https.onRequest(app); //React SSR
exports.updateChat = functions.database.ref('/chats/{chatId}/{messageId}').onCreate(updateChat);
Run Code Online (Sandbox Code Playgroud)

exports.app是一个react ssr函数,我正在使用它来托管我的网站。这也使用数据库。并抛出错误multiple database instance。当我逐一注释并部署时,效果很好。但是当我一起部署时不起作用。如何将这两个保持在相同的仓库中分开?有什么建议吗?

Shu*_*ham 4

您可以在导出功能之外初始化数据库。

const admin = require('firebase-admin');
const adminApp = admin.initializeApp(appOptions, 'app')
//continue code
Run Code Online (Sandbox Code Playgroud)

更新:

const admin = require('firebase-admin');
const adminApp = admin.initializeApp(appOptions, 'app')
//continue code
Run Code Online (Sandbox Code Playgroud)

根据您的需要修改此代码片段并尝试一下

它在另一个函数中抽象了应用程序的初始化。只需在代码中的适当位置调用此函数即可。