Firebase云功能查询不起作用

时间:2019-02-04 12:27:59

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

我通过以下查询部署了函数:

admin.firestore().collection("fcm").where("devices",'array-contains', mobile).get().then((snapshots)=> {...});

这会从云功能日志中返回以下错误:

msgTrigger: Function execution started

msgTrigger: Function returned undefined, expected Promise or value

msgTrigger: Function execution took 8429 ms, finished with status: 'ok'

msgTrigger: Unhandled rejection

msgTrigger: TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined at admin.firestore.collection.where.get.then (/user_code/index.js:23:65) at process._tickDomainCallback (internal/process/next_tick.js:135:7)

请问有人吗?

在这里与编辑战斗几天。决定分批发布我的功能代码:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
var msgData;
var mobile;

第二部分:

exports.msgTrigger = functions.firestore
  .document('Messages/{MessageID}')
  .onCreate((snapshot, context) => {
      msgData = snapshot.data();
      mobile = msgData.mobile;

      admin.firestore().collection("fcm").where("devices", 'array-contains', mobile).get().then((snapshots) => {

第三部分:

var tokens = [];
if (snapshots.empty) {
  console.log('No devices');
} else {
  for (var token of snapshot.docs) {
    tokens.push(token.data().token);
  }
  var payLoad = {
    "notification": {
      "title": "de " + msgData.name,
      "body": "Alerta de Emergência!",
      "sound": "default",
      "icon": msgData.icon
    },
    "data": {
      "remetente": +msgData.name,
      "mensagem": "Alerta de Emergência!"
    }
  }

第四部分:

return admin.messaging().sendToDevice(tokens, payLoad).then((response) => {
console.log("mensagens enviadas");
}).catch((err) => {
console.log("erro: " + err);
});
}
});

});

2 个答案:

答案 0 :(得分:0)

Firestore 0.8是一个很旧的版本,请参见https://cloud.google.com/nodejs/docs/reference/firestore/0.8.x/。只有从0.16版开始,您才能使用array-contains查询运算符,请参见https://github.com/googleapis/nodejs-firestore/releases/tag/v0.16.0。因此,您应该更新到最新版本。

我还通过首先返回第一个异步任务返回的promise(然后非常重要,请参见下文)来修改您的函数代码,然后在if / then / else中重新组织您的诺言链。

它现在可以正确执行吗?

   const functions = require('firebase-functions');
   const admin = require('firebase-admin');
   admin.initializeApp();  // Here changed, see https://firebase.google.com/docs/functions/beta-v1-diff#new_initialization_syntax_for_firebase-admin

   exports.msgTrigger = functions.firestore
      .document('Messages/{MessageID}')
      .onCreate((snapshot, context) => {
        const msgData = snapshot.data();  //No need to declare this outside of the Cloud Function, see https://www.youtube.com/watch?v=2mjfI0FYP7Y
        const mobile = msgData.mobile;

        return admin.   // <- HERE return
          .firestore()
          .collection('fcm')
          .where('devices', 'array-contains', mobile)
          .get()
          .then(snapshots => {
            let tokens = [];
            if (snapshots.empty) {
              console.log('No devices');
              return null;
            } else {
              for (var token of snapshot.docs) {
                tokens.push(token.data().token);
              }
              var payLoad = {
                notification: {
                  title: 'de ' + msgData.name,
                  body: 'Alerta de Emergência!',
                  sound: 'default',
                  icon: msgData.icon
                },
                data: {
                  remetente: +msgData.name,
                  mensagem: 'Alerta de Emergência!'
                }
              };
              return admin.messaging().sendToDevice(tokens, payLoad);
            }
          })
          .catch(err => {
            console.log('erro: ' + err);
            return null;
          });
      });

为什么返回异步任务返回的promise很重要?观看Firebase官方视频系列(https://firebase.google.com/docs/functions/video-series/)中有关“ JavaScript Promises”的3个视频,以获取答案!

删除“ .where('devices','array-contains',mobile)'会出现相同的错误。我将msgData.name和msgData.mobile添加到console.log并打印出来,所以第一部分就可以了:

1: 31: 05.140 AM
msgTrigger
Function execution started
1: 31: 11.289 AM
msgTrigger
Nome: Alan
1: 31: 11.291 AM
msgTrigger
mobile: 91983372845
1: 31: 11.291 AM
msgTrigger
erro: TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined
1: 31: 11.297 AM
msgTrigger
Function execution took 6158 ms, finished with status: 'ok'

And here is the fcm document

答案 1 :(得分:0)

Ok, for what it's worth I finally found the culprit:

for (var token of snapshot.docs) {

snapshot should be snapshots. Yes it's emabarrasing and it took nothing less than the excellent Firebase Support Team to point it out to me. Wished Android Studio could pick up this kind of silly typos in js code.

Will still mark Renaud's answer, since he helped optimize my code and gave me some usefull tips along the way.