如何从云功能中引用Firebase的实时数据库?

时间:2019-11-16 00:00:58

标签: node.js firebase firebase-realtime-database google-cloud-functions

在Firebase Cloud功能中,我试图从我的实时数据库中检索数据并向其写入更新。这是我遇到麻烦的地方。

功能:

const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp();
...

api.post('/messages/add', (request: any, response: any) => {

  const dbRef:any = functions.database.ref(`count/${request.body.chatRoomId}`);

  dbRef.once('value').then((snapshot:any) => {
      let messageCount:number = (snapshot.val() && snapshot.val().messages) || 0;
      messageCount = Number(messageCount + 1);
      dbRef.update({
        messages: messageCount,
        updated: admin.database().database.ServerValue.TIMESTAMP
      });
  });

});

当我从客户端调用此功能时,在Firebase云控制台日志中,我看到以下错误:

TypeError: dbRef.once is not a function

我曾尝试通过以下每种方式来引用数据库,但都失败了:

functions.database.ref(`count/${request.body.chatRoomId}`).once('value').then((snapshot)) =>

functions.database.ref(`count/${request.body.chatRoomId}`).once('value', (snapshot) =>

admin.database().ref(`count/${request.body.chatRoomId}`).once('value').then((snapshot)) =>

admin.database().ref(`count/${request.body.chatRoomId}`).once('value', (snapshot) =>

通过admin.database()使用Admin SDK尝试引用时,出现了另一个错误:

TypeError: Cannot read property 'ServerValue' of undefined
    at dbRef.once.then

最后,我可以确认${request.body.chatRoomId}的值是否正确解析,我已经通过将其值打印到控制台进行了测试。

答案here显示了如何从像onWrite()这样的实时数据库侦听器中的“事件”响应中引用实时数据库,但是我的功能不是由实时数据库更改触发的,而是是客户端可以访问的端点。

更新

下面由道格·史蒂文森(Doug Stevenson)提出的答案是正确的 ,但是由于尝试将时间戳错误地写入到我最初排除的字段中而导致函数运行,因此还有一个额外的错误尽管尝试了他的解决方案但还是失败了,所以我更新了代码以反映这一点。

首先,答案是使用admin.database()

引用实时数据库

第二,即使我尝试了此操作,我仍然看到错误,但是该错误是由于尝试错误设置时间戳导致的。感谢 Frank van Puffelen 指出这一点。

此:admin.database().database.ServerValue.TIMESTAMP

需要为:admin.database.ServerValue.TIMESTAMP

并且可以正常工作。

1 个答案:

答案 0 :(得分:2)

您在尝试使用功能SDK来查询数据库时犯了一个错误。这实际上不是在创建数据库引用:

functions.database.ref(`count/${request.body.chatRoomId}`);

function SDK仅用于声明和配置Cloud Functions。

您应该做的是使用Admin SDK创建参考,然后对其进行查询:

admin.database().ref(...).once(...)

使用前,您还需要初始化一次Admin SDK:

admin.initializeApp();