google-chromeservice-workerprogressive-web-appspush-api

What are the difference between `pushManager.subscribe` and `pushManager.getSubscription` Service Worker's


PushManager.getSubscription()

Retrieves an existing push subscription. It returns a Promise that resolves to a PushSubscription object containing details of an existing subscription. If no existing subscription exists, this resolves to a null value.

[...]

PushManager.subscribe()

Subscribes to a push service. It returns a Promise that resolves to a PushSubscription object containing details of a push subscription. A new push subscription is created if the current service worker does not have an existing subscription.

According to MDN's pushManager documentation. There methods are pretty much the same, except the point that in case of getSubcription() it may resolved with a null value.

I am basically understand that I can simply use subscribe() and Service Worker will try to get the subscription in case it available, and also create new one in case it not available.

=> But I was trying to do something else. I want to try to get subscription first, if it resolved with null I will try to subscribe it.

    navigator.serviceWorker.register('./worker.js')
    .then(function(reg) {

        // Subscribe push manager
        reg.pushManager.getSubscription()
        .then(function(subscription) {

            if(subscription){
                // TODO... get the enpoint here
            } else {
                reg.pushManager.subscribe()
                .then(function(sub){
                    // TODO... get the endpoint here
                });
            }

        }, function(error) {
            console.error(error);
        })
    });

But then I am ended up with the error:

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

It is confusing, and I am doubting this is a limitation of Chrome on Push API of Service Worker or can possibly a bug. Does any one has any information about this strange behavior?


Solution

  • The problem is that your service worker is registered, but it isn't active yet.

    You can use navigator.serviceWorker.ready instead of subscribing right after registering the service worker.

    If you want to make the service worker active as soon as possible, you can use skipWaiting and Clients.claim, as described in this ServiceWorker Cookbook recipe.