6

Ich verwende einen ServiceWorker, um Benutzerbenachrichtigungen zu implementieren. Wenn der Benutzer zuerst die Website besucht und genehmigt die Benachrichtigung, die Serviceworker registriert und abonnierten:Warten Sie, bis ServiceWorker die Registrierung abgeschlossen hat, bevor Sie sich anmelden.

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); 
}); 
} 

Auf dem ersten Besuch dieses Failes mit:

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

Ab dem zweiten Besuch, Alles ist in Ordnung, da der ServiceWorker zu diesem Zeitpunkt bereits aktiv ist. Sieht so aus, als wäre dies ein Timing-Problem. Wie kann ich sicher sein, dass der ServiceWorker erfolgreich registriert wurde und aktiv ist, bevor ich versuche, ihn zu abonnieren?

Ich versuchte navigator.serviceWorker.ready wie unten vorgeschlagen:

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); 
}); 
} 

Jetzt ist der Teil innerhalb navigator.serviceWorker.ready.then() nie genannt wird.

+0

Warum verwenden Sie die Push-API nur auf Chrome/Chromium? – Marco

+0

Da mein Backend derzeit nur GCM – Hokascha

+0

ohne Payloads unterstützt, ist der Web-Push-Standard sehr einfach zu implementieren (im Grunde eine POST-Anfrage an die Endpunkt-URL). – Marco

Antwort

5

Sie können ServiceWorkerContainer.ready verwenden.

Beispiel von 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; 
     } 
     }); 
    }); 
} 
+0

Können Sie ein Beispiel zeigen? In dem von Ihnen bereitgestellten Dokument gibt es keine Registrierung. Wo sollte der Aufruf ready() erfolgen? – Hokascha

+0

Ich habe ein Beispiel aus MDN hinzugefügt. – Marco

+0

Ah, vielleicht möchten Sie auch wissen, wie Sie den Service-Mitarbeiter beim ersten Laden der Seite aktivieren können? Sehen Sie sich https://serviceworke.rs/immediate-claim.html an. – Marco

Verwandte Themen