I'm trying to run a Web Application that sends push notifications when the window is inactive. To do this, I have a Service Worker that helps receives notifications from my php server (through Firebase).
However, I'm unsure how to check if the window is active through my Service worker. The Service Worker does not have access to the DOM, so I can't check it directly through there, and I've tried doing the checks on an attached JS file, but the Service Worker gets variable not defined errors. My Service Worker code is as follows:
self.addEventListener('push', function(event) {
console.log('[Service Worker] Push Received.');
// console.log(`[Service Worker] Push had this data: "${event.data.text()}"`);
const title = 'Chat';
const options = {
body: 'New message received!',
icon: '/images/logo/8-icon.png',
badge: '/images/badge.png'
};
event.waitUntil(self.registration.showNotification(title, options));
});
self.addEventListener('notificationclick', function(event) {
console.log('[Service Worker] Notification click Received.');
event.notification.close();
event.waitUntil(
clients.openWindow('https://localhost:8000')
);
});
Could anyone enlighten me on the proper way to check for an active window to prevent push notifications if the web app is active?
Thanks!
A: From a page on the same origin, go to Developer Tools > Application > Service Workers. You can also use chrome://inspect/#service-workers to find all running service workers.
You cannot use a service worker to control any window object. Service workers run in a worker context (not a browser context); it therefore has no DOM access. Since things like postMessage() is a window function, and window is part of the DOM, you cannot window. postMessage() from a service worker.
Because service-worker is able to send push notification only after I open the browser. If it is running in the background then it could have send notification even after closing browser also.
You can use the ServiceWorker WindowClient API to check whether the Window is visible or hidden.
async function checkClientIsVisible(): Promise<boolean> {
const windowClients = await clients.matchAll({
type: "window",
includeUncontrolled: true,
});
for (var i = 0; i < windowClients.length; i++) {
if (windowClients[i].visibilityState === "visible") {
return true;
}
}
return false;
}
You can use the visibility API -> https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API?redirectlocale=en-US&redirectslug=DOM%2FUsing_the_Page_Visibility_API
Attach an event listener on the main page to talk to your service worker. Then the service worker can execute accordingly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With