在长时间间隔使用后,Flutter FCM通知不一致

q5iwbnjs  于 6个月前  发布在  Flutter
关注(0)|答案(1)|浏览(59)

FCM快把我逼疯了。我开发了一个应用程序,在向Firestore写入时,触发一个云函数,该云函数向用户可以订阅的主题发送数据消息。如果应用程序被杀死或在后台,则此数据消息由后台函数接收,或者如果应用程序打开,则由前台的侦听器接收。两者都将处理消息并显示通知。
一切都很完美,然而,如果我几个小时不使用应用程序,然后启动它并尝试发送我的通知,它永远不会通过。我可以通过我的日志框架看到,数据被写入Firestore,云函数被触发并运行,它返回一个成功消息,没有错误,然后在云函数和我的应用程序之间的某个地方,它丢失了。我假设一些FCM后台进程保存了它。
现在,当这种情况发生时,我发现,如果我进入消息控制台并发送测试消息,它会通过,它似乎“重新唤醒”连接。在这样做之后,我可以再次发送通知,没有麻烦,直到我离开应用程序闲置了很长一段时间。
所以我有两个问题。
首先,是否有人对FCM显示类似行为有任何经验,如果有,你是否找到了修复它的方法。
其次,有没有人知道从FCM本身获取日志数据的方法。我的通知是从Cloud function -> FCM -> Device发送的。在FCM区域的某个地方,它会丢失或被保留。我不知道为什么,我找不到一种方法来获取日志,以揭示FCM在发送消息之前对我的消息所做的事情。
这是我的云函数(编辑了一些东西)

const {onDocumentCreated} = require("firebase-functions/v2/firestore");
const admin = require("firebase-admin");

admin.initializeApp({credential: admin.credential.applicationDefault()});

exports.functionNameHidden = onDocumentCreated("reports/{reportId}", (event) =>{
  const newReport = event.data.data();
  const message = {
    data: {
      message: newReport.userIdRef,
      hash: "hash hidden"
      id: event.data.id,
    },
    topic: "topic name hidden"
    android: {
      priority: "high",
    },
    apns: {
      headers: {
        "apns-push-type": "background",
        "apns-priority": "5",
      },
      payload: {
        aps: {
          contentAvailable: true,
        },
      },
    },
  };

  admin.messaging().send(message).then((response) => {
    // Response is a message ID string.
    console.log("Successfully sent message:", response);
    console.log(message);
  }).catch((error) => {
    console.log("Error sending message:", error);
  });
});

字符串
我的后台函数是这样处理的

@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp();
  var notification = message.data;
... more logic and local notification handling
}


在前台,我在initState中设置的侦听器中捕获通知

FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      var notification = message.data;
... more stuff
}


我很有信心,我的后台和前台处理的消息是不是问题,一旦连接到FCM是重新启动,他们都工作顺利。
我还将添加通知负载到我的云函数中,以便FCM发送通知而不是由我的应用处理的数据消息,这对我的实现来说并不好,所以我宁愿避免这种情况。

  • 这在iOS和Android上都是一致的
nwo49xxi

nwo49xxi1#

首先,我假设你使用的是android设备,因为你没有指定。
firebase文档中没有明确说明这一点,但仅数据消息并不意味着在应用程序处于后台时发送。我发现,有时在应用程序打开后短时间内空闲时可以接收到数据消息,但在较长时间后,您通常不会收到它。您所看到的不是错误,而是有意的行为。
以下是Android文档:
onMessageReceived适用于大多数消息类型,但以下情况除外:
当您的应用处于后台时发送的通知消息。在这种情况下,通知将发送到设备的系统托盘。默认情况下,用户点击通知将打开应用启动器。
在后台接收时,包含通知和数据有效负载的消息。在这种情况下,通知将被传递到设备的系统托盘,数据有效负载将在启动器Activity的Intent的extra中传递。
在iOS上,接收数据消息是可能的,但根据我的经验,在大多数情况下,你不能依赖于可传递性,尤其是在你一直在做任何测试的设备上,因为iOS对后台消息的限制非常大。
不幸的是,这意味着你可能无法通过FCM使用推送通知来完成你想要做的事情。不过,你可以使用潜在的替代方案。

轮询

你可以使用JobManager或WorkManager在Android上对你的服务器运行周期性的任务轮询。有各种插件可以帮助你做到这一点;我自己还没有使用过它们,所以你需要研究一下。

替代服务

大多数第三方“推送通知”服务只是在后台使用FCM和APNS。在Android上有自己的MQTT实现的一个选项是pushy.me,它可能对纯数据消息具有更好的可交付性。我相信它在iOS上使用APNS,所以你可能仍然有可交付性问题。

相关问题