Wait for ServiceWorker to complete registration before subscribing

I use ServiceWorker to implement user notifications. When a user first visits the site and approves the notification, ServiceWorker registers and subscribes 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); }); } 

In the very first visit this fails:

 Uncaught (in promise) DOMException: Subscription failed - no active Service Worker 

In the second visit, everything is fine, because ServiceWorker is already active at this time. It seems like a matter of time. How can I be sure that ServiceWorker has been successfully registered and active before I try to sign up for 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() never called.

+6
source share
1 answer

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; } }); }); } 
+5
source

All Articles