“TypeError:functions.firestore.collection不是函数”

时间:2018-04-03 17:23:39

标签: firebase google-cloud-functions google-cloud-firestore

通过Firestore文档,我看到了functions.firestore.document的许多示例,但我没有看到functions.firestore.collection的任何示例。 Firestore语法是

firebase.firestore().collection('...').doc('...')

我收到

的错误消息
firebase.firestore().document('...')

然而,在使用此代码的云函数中:

exports.myFunction = functions.firestore.collection('...').doc('...').onUpdate(event => {

在部署时我收到一条错误消息:

TypeError: functions.firestore.collection is not a function

当我将代码更改为

exports.getWatsonTokenFirestore = functions.firestore.document('...').onUpdate(event => {

我在部署时没有收到错误消息。

为什么云功能看起来与云端防火墙的数据结构不同?

这是我的完整云功能。我的收藏集是User_Login_Event,我的文档是Toggle_Value

    exports.getWatsonTokenFS = functions.firestore.document('User_Login_Event/{Toggle_Value}').onUpdate(event => {
              var username = 'TDK',
              password = 'swordfish',
              url = 'https://' + username + ':' + password + '@stream.watsonplatform.net/authorization/api/v1/token?url=https://stream.watsonplatform.net/speech-to-text/api';
              request({url: url}, function (error, response, body) {
admin.firestore().collection('IBM_Watson_Token').document('Token_Value').update('token');
              });
              return 0; // prevents an error message "Function returned undefined, expected Promise or value"
            });

该函数部署时没有错误但是当它执行时我收到此错误消息:

TypeError: firebase.firestore is not a function

我很困惑,因为firebase.firestore不在我的云功能中。它在我的Angular前端代码中的各个地方都没有问题。这个错误信息指的是什么?我尝试更改行

admin.firestore().collection('IBM_Watson_Token').document('Token_Value').update('token');

firebase.firestore().collection('IBM_Watson_Token').document('Token_Value').update('token');

console.log("getWatsonTokenFS response");

但是我收到了同样的错误消息。

4 个答案:

答案 0 :(得分:5)

是。您应该将其格式化为...

exports.getWatsonTokenFirestore = functions.firestore.document('myCollection/{documentId}').onUpdate(event => {
// code
});

collectiondocfirebase.firestore中的方法。要通过functions.firestore访问它们,您必须使用document

您可以查看Cloud Firestore的完整列表以及Cloud Functions for Firebase的最新SDK

更新

我一直在研究你的代码。我添加了所有依赖项和初始化,我在代码中假设 。我无法看到您在IBM Watson请求中使用Firestore中的任何数据,我无法看到您如何将任何返回的数据写回Firestore。由于我不熟悉您的request方法,我已将其评论出来,为您提供Firestore更新的实际示例,然后回复一些内容。我还编辑了一些代码以使其更具可读性并更改了Cloud Functions代码以反映今天发布的v1.0.0(我已经测试了一段时间):)

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

admin.initializeApp();

const firestore = admin.firestore();

exports.getWatsonTokenFS = functions.firestore
  .document('User_Login_Event/{Toggle_Value}')
  .onUpdate((snap, context) => {

    let username = 'TDK';
    let password = 'swordfish';
    let url = `https://${username}:${password}@stream.watsonplatform.net/authorization/api/v1/token?url=https://stream.watsonplatform.net/speech-to-text/api`;

    // request({url}, function (error, response, body) {
    // firestore.doc(`${IBM_Watson_Token}/${Token_Value}`).update('token');
    // });

    return firestore.doc(`IBM_Watson_Token/Token_Value`).update('token')
    .then(response => {
      return Promise.resolve();
    })
    .catch(err => {
      return Promise.reject(err);
    });
});

答案 1 :(得分:1)

现在Firebase已将firebase-admin更新为5.12.0并将firebase-functions更新为1.0.1,我的测试功能正常运行。除了两行之外,Jason Berryman写的函数是正确的。杰森写道:

.onUpdate((snap, context) => {

那应该是

.onUpdate((change, context) => {

其次,杰森写道:

return firestore.doc(`IBM_Watson_Token/Token_Value`).update('token')

更正后的行是:

return firestore.collection('IBM_Watson_Token').doc('Token_Value').update({
    token: 'newToken'
  })

我在Jason的代码中做了两处修改。首先,我改变了位置语法;更多关于这一点。其次,update()需要一个对象作为参数。

为了显示位置的语法,我编写了一个简单的云功能,当Cloud Firestore中某个位置的值发生更改时触发该功能,然后将新值写入Cloud Firestore中的其他位置。我删除了行const firestore = admin.firestore();以使代码更清晰:

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

admin.initializeApp();

exports.testFunction = functions.firestore.document('triggerCollection/{documentID}').onUpdate((change, context) => {

  return admin.firestore().collection('writeCollection').doc('documentID').update({
    token: 'newValue'
  })
  .then(response => {
    return Promise.resolve();
  })
  .catch(err => {
    return Promise.reject(err);
  });
});

让我们比较Cloud Firestore中三个位置的语法。首先,在浏览器中我使用以下语法:

firebase.firestore().collection('myCollection').doc('documentID')

接下来,在Cloud Function触发器中,我使用以下语法:

functions.firestore.document('myCollection/{documentID}')

第三,在Cloud Function返回中,我使用以下语法:

admin.firestore().collection('myCollection').doc('documentID')

第一行和最后一行是相同的,除了您使用firebase调用Firebase的浏览器,当您从服务器使用firebase-admin节点包调用Firebase时,此处别名为{{1} }。

中间线不同。它使用admin节点包调用Firebase,此处别名为firebase-functions

换句话说,使用不同的库调用Firebase,具体取决于您是从浏览器还是从服务器调用(例如,云功能),以及是否在云功能中调用了触发或返回。

答案 2 :(得分:0)

云功能是根据实时数据库中的Firebase示例中发生的事件进行触发的。

根据Firestore中发生的事件触发云端防火墙,该事件使用文档和集合的概念。

如下所述:

https://firebase.google.com/docs/functions/firestore-events

当文档发生更改时,将使用云Firestore触发器。

答案 3 :(得分:0)

我有同样的问题。我曾经关注

const getReceiverDataPromise = admin.firestore().doc('users/' + receiverUID).get();
const getSenderDataPromise = admin.firestore().doc('users/' + senderUID).get();

return Promise.all([getReceiverDataPromise, getSenderDataPromise]).then(results => {

        const receiver = results[0].data();
        console.log("receiver: ", receiver);

        const sender = results[1].data();
        console.log("sender: ", sender);

});