I am using a ServiceWorker to implement user notifications. When the user first visits the site and approves the notification, the ServiceWorker is registered and subscribed to:
if ('serviceWorker' in navigator) {
console.log('Service Worker is supported');
navigator.serviceWorker.register('/js/sw.js').then(function(reg) {
if(/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())){
reg.pushManager.subscribe({
userVisibleOnly: true
}).then(function(sub) {
console.log('endpoint:', sub.endpoint);
endpoint = sub.endpoint;
fetch(MY_API+encodeURIComponent(endpoint), {
credentials: 'include'
})
});
}
}).catch(function(err) {
console.log(':^(', err);
});
}
On the very first visit, this failes with:
Uncaught (in promise) DOMException: Subscription failed - no active Service Worker
From the second visit on, everything is OK because the ServiceWorker is already active at that time. Looks like this is a timing issue. How can I be sure the ServiceWorker has been registered successfully and is active before I try to subscribe to it?
I tried using navigator.serviceWorker.ready
as suggested below:
if ('serviceWorker' in navigator) {
console.log('Service Worker is supported');
navigator.serviceWorker.register('/js/sw.js').then(function(sreg) {
console.log(':^)', sreg);
navigator.serviceWorker.ready.then(function(reg) {
if(/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())){
reg.pushManager.subscribe({
userVisibleOnly: true
}).then(function(sub) {
console.log('endpoint:', sub.endpoint);
endpoint = sub.endpoint;
fetch("https://www.wettfreun.de/?page=fetch&s=1&endpoint="+encodeURIComponent(endpoint), {credentials: 'include'})
});
}
});
}).catch(function(err) {
console.log(':^(', err);
});
}
Now the part inside navigator.serviceWorker.ready.then()
is never called.
You can look at Service Worker Detector, a Chrome extension that detects if a website registers a Service Worker by reading the navigator. serviceWorker. controller property. It might also work in other browsers supporting Web Extensions, but it looks like it is not yet distributed as such.
Updating your service workerIt is only activated when there are no longer any pages loaded that are still using the old service worker. As soon as there are no more such pages still loaded, the new service worker activates. While this happens, the previous version is still responsible for fetches.
Once your service worker is ready to control clients and handle functional events like push and sync , you'll get an activate event.
You register a service worker to control one or more pages that share the same origin. The lifetime of a service worker registration is beyond that of the ServiceWorkerRegistration objects that represent them within the lifetime of their corresponding service worker clients.
You can use ServiceWorkerContainer.ready.
Example from MDN:
function subscribe() {
var subscribeButton = document.querySelector('.js-subscribe-button');
subscribeButton.disabled = false;
navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
serviceWorkerRegistration.pushManager.subscribe()
.then(function(subscription) {
// The subscription was successful
subscribeButton.disabled = true;
return sendSubscriptionToServer(subscription);
})
.catch(function(error) {
if (Notification.permission === 'denied') {
console.log('Permission for Notifications was denied');
subscribeButton.disabled = true;
} else {
console.log('Unable to subscribe to push.', error);
subscribeButton.disabled = false;
}
});
});
}
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