首页 > 解决方案 > 云功能有时不发送 FCM 通知

问题描述

我有一个云功能,它从数据库中读取一些数据,并在每天上午 10:00 向用户发送推送通知......

这是功能:

const functions = require('firebase-functions')
const admin = require('firebase-admin')
admin.initializeApp()

exports.qFunction = functions.region('europe-west3').pubsub.schedule('0 10 * * *').timeZone("Europe/Berlin").onRun((context) => {
    admin
      .firestore()
      .collection('users')
      .doc('hb')
      .get()
      .then((querySnapshot) => {
          var token = querySnapshot.data().tokens
          console.log(`Found user to: ${token}`)

          var now = new Date();
          var start = new Date(now.getFullYear(), 0, 0);
          var diff = (now - start) + ((start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000);
          var oneDay = 1000 * 60 * 60 * 24;
          var day = Math.floor(diff / oneDay);
          console.log('Day of year: ' + day);
          day += 1;
          
          admin
          .firestore()
          .collection('quotes')
          .doc(day.toString())
          .get()
          .then((querySnapshot) => {
            const payload = {
                notification: {
                  title: "HB",
                  body: querySnapshot.data().quote,
                  badge: '1',
                  sound: 'default'
                }
              }

              admin
              .messaging()
              .sendToDevice(token, payload)
              .then(response => {
                console.log('Successfully sent message:', response)
              })
              .catch(error => {
                console.log('Error sending message:', error)
              })
          })

      })
    return null;
  });

但是,有时它会发送通知,有时则不会。

比如前两天发送通知成功:

在此处输入图像描述

而今天它什么也没做:

在此处输入图像描述

这可能是什么原因?

因为我只有一个用户。可能是由于云功能冷启动吗?如果是,如何防止这种情况?

标签: node.jsgoogle-cloud-functionsfirebase-cloud-messaging

解决方案


您没有正确处理代码中的异步调用,这可能会导致您的代码在容器关闭时被中断。

为确保您的代码运行完成,请返回一个在所有异步操作完成后解析的承诺。在您的情况下,应该是这样的:

exports.qFunction = functions.region('europe-west3').pubsub.schedule('0 10 * * *').timeZone("Europe/Berlin").onRun((context) => {
    return admin //  
      .firestore()
      .collection('users')
      .doc('hb')
      .get()
      .then((querySnapshot) => {
          var token = querySnapshot.data().tokens
          console.log(`Found user to: ${token}`)

          var now = new Date();
          var start = new Date(now.getFullYear(), 0, 0);
          var diff = (now - start) + ((start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000);
          var oneDay = 1000 * 60 * 60 * 24;
          var day = Math.floor(diff / oneDay);
          console.log('Day of year: ' + day);
          day += 1;
          
          return admin //  
          .firestore()
          .collection('quotes')
          .doc(day.toString())
          .get()
          .then((querySnapshot) => {
            const payload = {
                notification: {
                  title: "HB",
                  body: querySnapshot.data().quote,
                  badge: '1',
                  sound: 'default'
                }
              }

              return admin //  
              .messaging()
              .sendToDevice(token, payload)
              .then(response => {
                console.log('Successfully sent message:', response)
              })
              .catch(error => {
                console.log('Error sending message:', error)
              })
          })

      })
    // return null;  //  
  });

在处理异步代码时,这种所谓的承诺冒泡是很正常的。我强烈建议您查看有关终止 Cloud Functions的 Firebase 文档以及从那里链接的 Doug 的视频系列。


推荐阅读