云功能有时不发送 FCM 通知

Cloud function sometimes doesn't send FCM notification

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

这是函数:

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;
  });

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

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

而今天它什么都没做:

这可能是什么原因?

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

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

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

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;  //  
  });

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