Search code examples
push-notificationservice-workerweb-pushpush-api

Multiple Chrome push notifications automatically closes except the last one


I have a Service Worker that fetches multiple notifications from the server. The problem is all notifications in Chrome automatically closes except the last one. What am I doing wrong?

self.addEventListener('push', function(event) {
var subscriptionId;
var sessionId;
var notification = {};

event.waitUntil(
    self.registration.pushManager.getSubscription().then(function(subscription) {
        subscriptionId = subscription.endpoint.split('/');
        subscriptionId = subscriptionId[subscriptionId.length - 1];

        notification.title = 'Yay a message.';
        notification.icon = '/app/img/icon-256x256.png';
        notification.tag = 'notification-tag-' + (new Date)*1;
        notification.messages = [];

        //get context
        fetch(requestUrl,
            {
                method: 'post',
                body: body
            }).then(function(response) {
                response.json().then(function(data) {
                    sessionId = response.headers.get('SessionId');
                    fetch(requestUrl + '?SessionId=' + sessionId, {
                        method: 'post',
                        headers: JSON.stringify({
                            'Content-Type': 'application/json'
                        }),
                        body: JSON.stringify({
                            data: {
                                subscriberId: subscriptionId
                            }
                        })
                    }).then(function(responce) {
                        responce.json().then(function(data) {
                            data = data.data;
                            if (!data.chromeNotifications || !data.chromeNotifications.length) return;
                            data.chromeNotifications.forEach(function(push) {
                                notification.messages.push(push.message);
                            });
                        }).then(function() {
                            var promises = [];
                            for(var i=0; notification.messages && i<notification.messages.length; i++) {
                                promises.push(self.registration.showNotification(notification.title, {
                                    body: notification.messages[i],
                                    icon: notification.icon,
                                    tag: notification.tag
                                }));
                            }
                            return Promise.all( promises );
                        });
                    });
                })
            });
    }).catch(function(error) {
        console.error('Unable to get subscription data', error);
        var title = 'An error occurred';
        var message = 'We were unable to get the information for this push message';
        var notificationTag = 'notification-error';
        return self.registration.showNotification(title, {
            body: message,
            tag: notificationTag
        });
    })
);

Solution

  • Just before fetching the pending notifications from your server, on line 13 of your example, you set the tag once to be unique for the incoming Push message. This tag is then being used for each of the messages fetched from your server, on line 47.

    The tag of a notification can be used to indicate that, when created, the notification should try to replace any previous notification sharing the same tag prior to displaying a brand new one. In this case, you are repeatedly overwriting your previous notifications.

    The solution is to not use tag at all, since you want it to be unique anyway. It does make sense to keep it for your error notification - it doesn't help users if you show it twice.