Chrome Push Notification: This site has been updated in the background
Solution 1
Generally as soon as you receive a push message from GCM (Google Cloud Messaging) you have to show a push notification in the browser. This is mentioned on the 3rd point in here:
So it might happen that somehow you are skipping the push notification though you got a push message from GCM and you are getting a push notification with some default message like "This site has been updated in the background".
Solution 2
I was expriencing the same issue but after a long research I got to know that this is because delay happen between PUSH event and self.registration.showNotification(). I only missed return keyword before self.registration.showNotification()
So you need to implement following code structure to get notification:
var APILINK = "https://xxxx.com";
self.addEventListener('push', function(event) {
event.waitUntil(
fetch(APILINK).then(function(response) {
return response.json().then(function(data) {
console.log(data);
var title = data.title;
var body = data.message;
var icon = data.image;
var tag = 'temp-tag';
var urlOpen = data.URL;
return self.registration.showNotification(title, {
body: body,
icon: icon,
tag: tag
})
});
})
);
});
Solution 3
I've run into this issue in the past. In my experience the cause is generally one of three issues:
- You're not showing a notification in response to the push
message. Every time you receive a push message on the device, when
you finish handling the event a notification must be left visible on
the device. This is due to subscribing with the
userVisibleOnly: true
option (although note this is not optional, and not setting it will cause the subscription to fail. - You're not calling
event.waitUntil()
in response to handling the event. A promise should be passed into this function to indicate to the browser that it should wait for the promise to resolve before checking whether a notification is left showing. - For some reason you're resolving the promise passed to
event.waitUntil
before a notification has been shown. Note thatself.registration.showNotification
is a promise and async so you should be sure it has resolved before the promise passed toevent.waitUntil
resolves.
Solution 4
I was trying to understand why Chrome has this requirement that the service worker must display a notification when a push notification is received. I believe the reason is that push notification service workers continue to run in the background even after a user closes the tabs for the website. So in order to prevent websites from secretly running code in the background, Chrome requires that they display some message.
What are the limitations of push messaging in Chrome?
...
- You have to show a notification when you receive a push message.
...
and
Why not use Web Sockets or Server-Sent Events (EventSource)?
The advantage of using push messages is that even if your page is closed, your service worker will be woken up and be able to show a notification. Web Sockets and EventSource have their connection closed when the page or browser is closed.
Solution 5
If you need more things to happen at the time of receiving the push notification event, the showNotification()
is returning a Promise
. So you can use the classic chaining.
const itsGonnaBeLegendary = new Promise((resolve, reject) => {
self.registration.showNotification(title, options)
.then(() => {
console.log("other stuff to do");
resolve();
});
});
event.waitUntil(itsGonnaBeLegendary);
Admin
Updated on July 20, 2022Comments
-
Admin almost 2 years
While implementing the chrome push notification, we were fetching the latest change from our server. While doing so, the service-worker is showing an extra notification with the message
This site has been updated in the background
Already tried with the suggestion posted here https://disqus.com/home/discussion/html5rocks/push_notifications_on_the_open_web/
But could not find anything useful till now. Is there any suggestion ? -
Ripon Al Wasim almost 9 yearsWhat does GCM stand for?
-
Aaron about 8 yearsFor anyone else that has this issue, it's not only "self.registration.showNotification" that needs to be returned. Every single nested function needs to return a promise. I found this out via this post: stackoverflow.com/a/33187502/1451657
-
owencm about 8 yearsNote that you must in fact show a notification before resolving the promise you pass into event.waitUntil(). Essentially by passing a promise into that you're saying "I'm done when this resolves, and at that time feel free to verify I showed a notification to my users"
-
Mehul Tandale over 7 years@Yogendra: So I need to make a API for the content?
-
Yogendra over 7 years@Mehul Tandale, Yes you need to make a API for content to show in notification slider. but now chrome started delivering arbitrary content (Payload) too, that you can further explore.
-
Mehul Tandale over 7 yearsThanks for clarifying @Yogendra
-
jaafar Nasrallah over 7 yearsin other words, as mentioned in @Yogendra 's answer, you need to return the show notification so that the notification is solved before the promise is resolved
-
Admin about 6 yearsThat link is old, check my answer (2018)
-
Admin about 6 yearsI have a simplified answer, check below.
-
nilsmagnus over 5 yearsThis answer is valid also for firebase(FCM) notifiactions.
-
Dev over 4 yearsI have the same issue when handling web app foreground push notification with Firebase FCM JS SDK. When my web app is on foreground, I get the notification payload from onMessage() listener, then using this code block to show notification on notification tray, and finally I got 2 notification (one by myselft and one is "This site has been update..."):
navigator.serviceWorker.ready.then(registration => { registration.showNotification(title, options); });
-
Carl G over 4 yearsDo all registered notification service workers restart when Chrome (desktop) is started?
-
Anthony over 3 yearsThat makes sense to me