Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 用于推送通知的Firebase功能-“;错误:只需要主题、标记或条件中的一个";_Node.js_Firebase_Google Cloud Functions_Firebase Cloud Messaging - Fatal编程技术网

Node.js 用于推送通知的Firebase功能-“;错误:只需要主题、标记或条件中的一个";

Node.js 用于推送通知的Firebase功能-“;错误:只需要主题、标记或条件中的一个";,node.js,firebase,google-cloud-functions,firebase-cloud-messaging,Node.js,Firebase,Google Cloud Functions,Firebase Cloud Messaging,我试图在Firebase上使用云函数发送推送通知。最终目标是每当有人写入数据库中的特定位置时,向所有用户推送通知/model\u outputs/real\u estate。我已经确认,当我在数据库中手动创建节点时,该函数将激活。尽管如此,当它运行时,我看到了以下错误: Error: Exactly one of topic, token or condition is required at FirebaseMessagingError.FirebaseError [as constr

我试图在Firebase上使用云函数发送推送通知。最终目标是每当有人写入数据库中的特定位置时,向所有用户推送通知
/model\u outputs/real\u estate
。我已经确认,当我在数据库中手动创建节点时,该函数将激活。尽管如此,当它运行时,我看到了以下错误:

Error: Exactly one of topic, token or condition is required
    at FirebaseMessagingError.FirebaseError [as constructor] (/srv/node_modules/firebase-admin/lib/utils/error.js:42:28)
    at FirebaseMessagingError.PrefixedFirebaseError [as constructor] (/srv/node_modules/firebase-admin/lib/utils/error.js:88:28)
    at new FirebaseMessagingError (/srv/node_modules/firebase-admin/lib/utils/error.js:254:16)
    at Object.validateMessage (/srv/node_modules/firebase-admin/lib/messaging/messaging-types.js:46:15)
    at Messaging.send (/srv/node_modules/firebase-admin/lib/messaging/messaging.js:216:27)
    at children.map.child (/srv/index.js:59:37)
    at Array.map (<anonymous>)
    at admin.database.ref.once.then.then.children (/srv/index.js:50:24)
    at <anonymous>
    at process._tickDomainCallback (internal/process/next_tick.js:229:7)
  errorInfo: 
   { code: 'messaging/invalid-payload',
     message: 'Exactly one of topic, token or condition is required' },
  codePrefix: 'messaging'
}))

我必须承认我没有写这个函数,所以如果它可以改进,我将非常感激。我的角度和javascript知识相当基础

您可以看到,我正试图将我的用户令牌传递到一个数组中,然后向所有这些用户发送一条消息。令牌存储在我的数据库中的
/fcmTokens
,如下所示:


考虑到消息错误,似乎未正确设置
子.device\u token
变量中的值,并且发送时没有值。我建议您在发送值并确认之前打印它


完成此操作并确认问题存在后,只需更改在
令牌中发送值的方式,以便可以在消息中发送正确的值。

Hi@Kellen与此类似,在向FCM发送空令牌时,似乎会引发错误。请检查并确认您是否发送了空邮件?这可以解释问题。@gso_gabriel,我看到了那篇帖子。您建议如何验证这一点?@gso_gabriel,因此我可以使用:
let children=[]将其中一个令牌打印到控制台;forEach(child_snap=>{children.push(child_snap.val());console.log(children[1]);})它看起来好像要通过了。从以前的测试来看,foreach循环似乎循环了两次,此时数据库中只有两个令牌。如果打印
child.device\u token
?你有价值吗?在测试中,您读取整个数组,确认您有一个令牌,但不在该特定部分。除此之外,您是否希望在特定情况下发送给特定用户,对吗?您似乎想使用通知,但实际上不是。@gso\u gabriel,好的,所以我将
child.device\u token
记录到
let message
声明正上方的控制台上,它返回时未定义。当我把这段代码复制过来时,我完全忽略了这一点。我将其更改为
child
,它现在似乎正在记录令牌。成功了!
exports.sendNoti =
    functions.database.ref('/model_outputs/real_estate')
    .onWrite((change, context) => {

  return admin.database().ref("/fcmTokens").once('value')
      .then(snap => {
          let children = [];
          snap.forEach(child_snap => {
              children.push(child_snap.val());
              console.log('get token'); // build children
          });

          return children;
      })
      .then(children => {
          children.map(child => {
              let message = {
                  notification: {
                      title: "test",
                      body: "body"
                  },
                  token: child.device_token
              }

              admin.messaging().send(message).catch(console.log);
          });

          return null;
      })
      .then( () => { 
          return notif.ref.remove(); // consume send request
      })
      .catch(console.log);