在每次执行中发送多个推送通知的Firebase函数中*返回*的内容是什么?

时间:2017-08-05 17:33:14

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

我正在使用单个firebase功能向我的Android用户发送多个推送通知。

每个通知的详细信息都会在我们的Firebase数据库中写下它们应发送的日期和小时。我使用cron通过http请求触发此Firebase函数。

我的问题是Firebase功能返回应该是什么才能完成所有Firebase节点的循环(代表通知)并完成发送所有通知?

这就是我现在所拥有的。它在发送第一个通知后退出。我想要的是它完成所有Firebase子节点的查看并为每个节点发送通知。

我不明白Promises的想法足以弄清楚在多个Push Notifications的情况下返回什么。我几乎完全忘记了如何编写javascript也无济于事。

exports.sendHourlyNotifications = functions.https.onRequest((req, res) => {
  const dateStr = req.query.date;
  const hourStr = req.query.hour;
  console.log('sendHourlyNotifications', 'date: ' + dateStr + " hour: " + hourStr);
  const parentRef = admin.database().ref();
  const notifRef = parentRef.child('all-notifications');
  const hourRef = notifRef.child(dateStr).child(hourStr);
  return hourRef.once('value').then(snapshot => {
      const updates = {};
      snapshot.forEach(function(childSnapshot) {
        const deviceToken = childSnapshot.child("deviceToken").val();
        console.log('sendHourlyNotifications', 'childSnapshot Key: ' + childSnapshot.key);
        const title = childSnapshot.child("title").val();
        const body = childSnapshot.child("body").val();

        console.log('sendHourlyNotifications', "DeviceToken: " + deviceToken + " Title: " + title + " Body: " + body);

          var payload = {
                notification: {
                  title: title,
                  body: body,
                }
              };

          admin.messaging().sendToDevice(deviceToken, payload);

          return Promise.all([
            /* ... */
          ]).then(() => {
            res.status(200).send('ok');
          }).catch(err => {
            console.log(err.stack);
            res.status(500).send('error');
          });
      });
      return parentRef.update(updates);
  });
});

如果无法在同一个Firebase功能执行中发送多个推送通知,那么我想我将不得不重新架构一下。如果是这种情况,我欢迎任何提示或示例链接到更好的设计。

1 个答案:

答案 0 :(得分:5)

由于此功能是由HTTP请求触发的,因此您无需从顶级功能返回任何内容。一旦您致电send,该功能即被视为已完成。

因此,您需要做的是重构代码,在您发送所有通知后才调用send()

return hourRef.once('value').then(snapshot => {
  var promises = [];
  snapshot.forEach(function(childSnapshot) {
    const deviceToken = childSnapshot.child("deviceToken").val();
    const title = childSnapshot.child("title").val();
    const body = childSnapshot.child("body").val();

    var payload = {
        notification: {
          title: title,
          body: body,
        }
      };
    promises.push(admin.messaging().sendToDevice(deviceToken, payload));

  });
  // The res.send() needs to be outside of the snapshot.forEach() callback
  Promise.all(promises).then(() => {
    res.status(200).send('ok');
  }).catch(err => {
    console.log(err.stack);
    res.status(500).send('error');
  });

});

如果你是"新"对于JavaScript,Firebase的云功能并不是学习它的最佳方式。我建议先阅读Firebase documentation for Web developers和/或Firebase codelab for Web developer。它们涵盖了许多基本的JavaScript,Web和Firebase交互。您还可以在本地Node.js进程中使用Admin SDK,该进程可以使用本地调试器进行调试。在那些之后,您也可以更好地为云功能编写代码。