Wait for ServiceWorker to complete registering before subscribing

Viewed 8767

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.

1 Answers
Related