firebasepush-notificationfirebase-cloud-messagingweb-push

Firebase web Push notifications is triggered twice when using onBackgroundMessage()


I really don't know what is going on with these things. I am using FCM web push normally for my website. I can receive the message on the website if I am in foreground or I receive the notification if I am in the background. So far so good.

importScripts('https://www.gstatic.com/firebasejs/8.2.5/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/8.2.5/firebase-messaging.js');

firebase.initializeApp({
  ...
});

const messaging = firebase.messaging();

The problem is that the default configuration of firebase-messaging-sw.js displays a notification in the background showing the chrome icon. I want to be able to customize this notification and display my application icon. Then reading on the web I found that I need to intercept the message with onBackgroundMessage().

importScripts('https://www.gstatic.com/firebasejs/8.2.5/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/8.2.5/firebase-messaging.js');

firebase.initializeApp({
  ...
});

const messaging = firebase.messaging();

if (messaging) {
  messaging.onBackgroundMessage(payload => {
    const notificationTitle = payload.notification.title || payload.data.title;
    const notificationOptions = {
      body: payload.notification.body || payload.data.subtitle || '',
      icon: 'https://firebasestorage.googleapis.com/v0/b/yes-4-web.appspot.com/o/pontonos%2Ficons%2Fandroid-chrome-192x192.png?alt=media&token=35616a6b-5e70-43a0-9284-d780793fa076',
      data: payload.data
    };

    return self.registration.showNotification(notificationTitle, notificationOptions);
  });

  self.addEventListener('notificationclick', event => {
    event.notification.close();
    event.waitUntil(clients.matchAll({ type: "window" }).then(function(clientList) {
      for (let i = 0; i < clientList.length; i++) {
        const client = clientList[i];
        if (client.url === '/' && 'focus' in client) {
          if (event.notification.data.route) client.href(event.notification.data.route);
          return client.focus();
        }
      }
      if (clients.openWindow)
        return clients.openWindow(event.notification.data.route || '/');
    }));
  });
}

The problem is that now, when using onBackgroundMessage(), two notifications appear to me, the original with the chrome icon and my personalized message with my application icon (see image)

notifications

Another problem is that if I click on the original notification, the tab with my website comes to the main focus, but if I click on the personalized notification, a new tab opens with my website.


Solution

  • Probably too late.

    I had this issue and the problem, as I eventually figured out, was that I was sending 'notification' and 'data' objects in my payload.

    Removing 'notification' and leaving just 'data' solved the problem.

    From FCM docs:

    Use notification messages when you want FCM to handle displaying a notification on your client app's behalf. Use data messages when you want to process the messages on your client app.

    FCM can send a notification message including an optional data payload. In such cases, FCM handles displaying the notification payload, and the client app handles the data payload.

    Here's what my payload now looks like:

    $payload = [
                'message' => [
                    'token' => $token,
                    'data'  => $msg,
                    //'notification'  => $msg, (this caused the notification to deliver twice)
                    'webpush'=> [
                      'fcm_options'=> [
                        'link' => $link,
                        'analytics_label' => 'notification_label'
                      ]
                    ]
                ],
            ];
    

    https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages