onMessage:在传入消息上两次调用回调

时间:2020-09-09 07:32:28

标签: firebase flutter firebase-cloud-messaging flutter-web

在我的应用程序中,对于Web版本,我将软件包firebase 7.3.0用于Firebase服务,并且现在也正在为Web设置FCM。 当我在前台使用该应用收到新消息时,来自onMessage:的{​​{1}}被触发两次。在某些Flutter版本之前,messaging()设备插件也曾经发生过这种情况,但现在已解决。

我基本上设置了一个flutter_messaging来获取与StreamTransformer中使用的Map<String, dynamic>设备包相同类型的flutter_messaging消息,我使用一个Stub来切换类取决于平台。 在网络类PlatformPushNotificationDevice中,我将消息传递实例化为PlatformPushNotificationWeb并声明了我的方法,其中之一是var firebaseMessaging = messaging();

onMessage()

所以无论平台如何,我集团中的侦听器都将收到相同的消息类型,

Stream<Map<String, dynamic>> onMessage()  async* {

    print('PlatformPushNotificationWeb.onMessage() started');
    handleData(Payload payload, EventSink<Map<String, dynamic>> sink) {
        Map<String,dynamic> message = {
          'notification': {
            'title': payload.notification.title,
            'body': payload.notification.body,
            'sound': true
          },
          'data': payload.data
        };
      sink.add(message);
    }

    final transformer = StreamTransformer<Payload, Map<String, dynamic>>.fromHandlers(
        handleData: handleData);

    yield* firebaseMessaging.onMessage.transform(transformer);
  }

但是对于每条传入的消息,我都会让侦听器响应两次。

我将Stream<PushNotificationState> _mapListenToMessagesToState(ListenToMessages event) async* { print('_mapListenToMessagesToState started'); _pushNotificationSwitcher.onMessage().listen((message) { print('_mapListenToMessagesToState onMessage() listener: received new message'); add(ReceivedNewMessage(message: message)); }); } 设置为:

index.html

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>fixit cloud biking</title> <!-- <meta name="google-signin-client_id" content="YOUR_GOOGLE_SIGN_IN_OAUTH_CLIENT_ID.apps.googleusercontent.com">--> <meta name="google-signin-client_id" content="xxxx.apps.googleusercontent.com"> <!-- <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">--> </head> <!--<body>--> <body id="app-container"> <script src="main.dart.js?version=45" type="application/javascript"></script> <!-- The core Firebase JS SDK is always required and must be listed first --> <script src="https://www.gstatic.com/firebasejs/7.19.1/firebase-app.js"></script> <!-- TODO: Add SDKs for Firebase products that you want to use https://firebase.google.com/docs/web/setup#available-libraries --> <script src="https://www.gstatic.com/firebasejs/7.19.1/firebase-auth.js"></script> <script src="https://www.gstatic.com/firebasejs/7.19.1/firebase-analytics.js"></script> <script src="https://www.gstatic.com/firebasejs/7.19.1/firebase-messaging.js"></script> <script src="https://www.gstatic.com/firebasejs/7.19.1/firebase-storage.js"></script> <script src="https://www.gstatic.com/firebasejs/7.19.1/firebase-database.js"></script> <script src="https://www.gstatic.com/firebasejs/7.19.1/firebase-remote-config.js"></script> <script> if ("serviceWorker" in navigator) { window.addEventListener("load", function () { //navigator.serviceWorker.register("/flutter_service_worker.js"); navigator.serviceWorker.register("/firebase-messaging-sw.js"); }); } </body> </html> 文件为:

firebase-messaging-sw.js

是否可能是在importScripts("https://www.gstatic.com/firebasejs/7.19.1/firebase-app.js"); importScripts("https://www.gstatic.com/firebasejs/7.19.1/firebase-messaging.js"); firebase.initializeApp({ apiKey: "xxxx", authDomain: "xxxx", databaseURL: "xxxx", projectId: "xxx", storageBucket: "xxxx", messagingSenderId: "xxxx", appId: "xxx", measurementId: "G-xxxx", }); const messaging = firebase.messaging(); messaging.setBackgroundMessageHandler(function (payload) { console.log('[firebase-messaging-sw.js] Received background message ', payload); const promiseChain = clients .matchAll({ type: "window", includeUncontrolled: true }) .then(windowClients => { for (let i = 0; i < windowClients.length; i++) { const windowClient = windowClients[i]; windowClient.postMessage(payload); } }) .then(() => { return registration.showNotification("New Message"); }); return promiseChain; }); self.addEventListener('notificationclick', function (event) { console.log('notification received: ', event) }); 类和PlatformPushNotificationWeb文件中实例化消息传递导致firebase-messaging-sw.js回调被触发两次的原因? 非常感谢。

1 个答案:

答案 0 :(得分:0)

事实证明..很好的清理,Android Studio和机器重启解决了这个问题。

现在我不会两次收到相同的消息,但是对于那些实际上正在尝试重复消息的人来说,这将解决该问题,但这只是一种解决方法。

只需声明int lastMessageId = 0变量。 收到邮件时,请对照其id进行检查,并且只有它们不同时,才将新的邮件ID保存为lastMessageId并显示该邮件。

Stream<PushNotificationState> _mapListenToMessagesToState(ListenToMessages event) async* {
    print('_mapListenToMessagesToState started');
    int lastMessageId = 0;

    _pushNotificationSwitcher.onMessage().listen((message) {
      print('incoming message is : $message');
      var data = message['data'];
      int messageId = int.parse(data['id']);

      if( lastMessageId != messageId) {
        lastMessageId = messageId;
        print(
            '_mapListenToMessagesToState onMessage() listener: received new message');
        add(ReceivedNewMessage(message: message));
      }
    });
  }