要在每次执行中发送多个推送通知的Firebase函数*返回*?

Kai*_*han 2 node.js firebase-realtime-database google-cloud-functions firebase-cloud-messaging 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);
  });
});
Run Code Online (Sandbox Code Playgroud)

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

Fra*_*len 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');
  });

});
Run Code Online (Sandbox Code Playgroud)

如果您是JavaScript的"新手",Firebase的Cloud Functions不是学习它的最佳方式.我建议首先阅读面向Web开发人员Firebase文档和/或为Web开发人员使用Firebase codelab.它们涵盖了许多基本的JavaScript,Web和Firebase交互.您还可以在本地Node.js进程中使用Admin SDK,该进程可以使用本地调试器进行调试.在那些之后,您将更好地为云功能编写代码.