首页 > 解决方案 > Firestore 推送通知“超时”错误通知并不总是被发送

问题描述

我正在从我的应用程序中调用一个函数,该函数向应用程序上的特定用户发送通知。通知大部分时间都成功发送,但很多时候它没有发送。当它没有被发送时,我检查日志以查看

函数执行耗时 60003 毫秒,完成状态为:'timeout'

我尝试过使用我的承诺/异步等待,但没有运气,因为我怀疑这就是问题所在。

这是我的云代码现在的样子

exports.sendNotification = functions.https.onRequest(async (request, response) => {

    if (request.method !== "POST") {
        response.status(400).send("Send it using post request");
        return;
    }

    var toUid = request.body.toUid
    var fcm = request.body.fcm
    var fromUid = request.body.fromUid
    var type = request.body.type
    var fromName = request.body.fromName
    var messageText = request.body.message

    if (toUid === "" || fromUid === "" || fcm === "") {
        response.status(400).send("Parameter is missing!");
        return;
    }

    // common data for both platforms
    const notification = {
     title: fromName,
     body: messageText,
    }
    const fcmToken = fcm

    // ios specific headers
    const apns = {
      headers: {
        "apns-collapse-id": 'toUid'
      },
      payload: {
        aps: {
          sound: 'default'
        },
        "data": {
          "fromUid": fromUid,
          "type": type
        }
      }
    }

    // final message
    const message = {
     token: fcmToken,
     notification: notification,
     apns: apns,
    }

    // send message
    try {
      return await admin.messaging().send(message);
      response.status(200).send("Done");
    } catch(e) {
      console.log('Error sending message:', e);
    }
});

我从应用程序调用函数如下

         AF.request("https://myproject.net/sendNotification", method: .post, parameters: parameters, encoding: JSONEncoding.default)
         .responseString { response in
             print(response)
            DispatchQueue.main.async {
                completion("done")
            }
         }

我已经看到其他类似问题的stackoverflow问题,建议使用 .post 和 JSONEncoding.default ,这就是我现在所拥有的。

标签: javascriptswift

解决方案


来自https://firebase.google.com/docs/functions/http-events#terminate_http_functions

在您的 catch 块中没有调用.send()或任何等效项,所以从上面的链接:

始终使用 send()、redirect() 或 end() 结束 HTTP 函数。否则,您的函数可能会继续运行并被系统强制终止。另请参阅同步、异步和承诺。

此外,最好将整个代码包装onRequest在 try/catch 中的回调中。

这是带有建议修复的代码:

exports.sendNotification = functions.https.onRequest(async (request, response) => {

  try {

    if (request.method !== "POST") {
      response.status(400).send("Send it using post request");
      return;
    }

    var toUid = request.body.toUid
    var fcm = request.body.fcm
    var fromUid = request.body.fromUid
    var type = request.body.type
    var fromName = request.body.fromName
    var messageText = request.body.message

    if (toUid === "" || fromUid === "" || fcm === "") {
      response.status(400).send("Parameter is missing!");
      return;
    }

    // common data for both platforms
    const notification = {
      title: fromName,
      body: messageText,
    }
    const fcmToken = fcm

    // ios specific headers
    const apns = {
      headers: {
        "apns-collapse-id": 'toUid'
      },
      payload: {
        aps: {
          sound: 'default'
        },
        "data": {
          "fromUid": fromUid,
          "type": type
        }
      }
    }

    // final message
    const message = {
      token: fcmToken,
      notification: notification,
      apns: apns,
    }

    // send message
    await admin.messaging().send(message); // do not return here
    response.status(200).send("Done");

  } catch (e) {
    response.status(500).send(e) // note the .send() wich terminates the request
  }
});

推荐阅读