Even though it's not possble to revoke push messages, it is possible to close one, using:
// app.js
navigator.serviceWorker.ready.then(reg => {
reg.getNotifications().then(notifications => {
for (let i = 0; i < notifications.length; i += 1) {
notifications[i].close();
}
});
});
You could even send a new WebPush message from the back-end with a special action in the payload, for example data: { action: 'close', id: 123 }
to trigger messages to be closed. The 'push' eventListener can relay a 'message' event to all clients to close the given (or all) open notifications.
// sw.js
self.addEventListener('push', event => {
let opts = event.data.json();
if (opts.data && opts.data.action) {
event.waitUntil(clients.matchAll().then(windowClients => {
for (let i = 0; i < windowClients.length; i += 1) {
windowClients[i].postMessage(opts.data);
}
});
}
});
// app.js
navigator.serviceWorker.addEventListener('message', event => {
if (event.data && event.data.action && event.data.action === 'close') {
closeNotification(event.data.id);
}
});
function closeNotification(id) {
navigator.serviceWorker.ready.then(reg => {
reg.getNotifications().then(n => {
for (let i = 0; i < n.length; i += 1) {
if (n[i].data && n[i].data.id && n[i].data.id === id) {
n[i].close();
}
}
});
});
}
The biggest downside is that this method only works for active / open clients. I haven't found a way around that.
Used sources: