OneSignal registration fails after refresh

Viewed 1773

I am using OneSignal in my Laravel/Vue app. I have included it within <head> as stated in documentation:

<script src="https://cdn.onesignal.com/sdks/OneSignalSDK.js" async=""></script>
<script>
    var OneSignal = window.OneSignal || [];
    OneSignal.push(function() {
        OneSignal.init({
            appId: "{{ env('ONESIGNAL_APP_ID') }}"
        });
        OneSignal.showNativePrompt();
    });
</script>

<script>

    if ('serviceWorker' in navigator) {
        navigator.serviceWorker.register('/OneSignalSDKWorker.js')
            .then(function () {
                console.log('Service worker registered');
            })
            .catch(function (error) {
                console.log('Service worker registration failed:', error);
            });
    } else {
        console.log('Service workers are not supported.');
    }

</script>

I also have a service worker of my own, so I've followed the documentation here as well.

What is happening after a hard reset is that service worker gets installed and it is all fine, however once I refresh the page I am getting:

OneSignalPageSDKES6.js?v=151102:1 Uncaught (in promise) InvalidStateError: The current environment does not support this operation. at Function.getServiceWorkerHref (https://cdn.onesignal.com/sdks/OneSignalPageSDKES6.js?v=151102:1:41510) at xe. (https://cdn.onesignal.com/sdks/OneSignalPageSDKES6.js?v=151102:1:144028) at Generator.next () at r (https://cdn.onesignal.com/sdks/OneSignalPageSDKES6.js?v=151102:1:716)

And I have no idea what does that mean? What is "current environment"? Where to start debugging? I've tried putting console logs around it, however it led me nowhere...

1 Answers

You would start debugging by looking at the source code of the library.

In your case your library is the OneSignal SDK for browsers.

Let's do this!!!

We can see that this error is thrown by getServiceWorkerHref function (which is defined here) and the error message is driven by the InvalidStateReason enumeration:

      case InvalidStateReason.UnsupportedEnvironment:
        super(`The current environment does not support this operation.`);
        break;

If you look at the first linked file, you will see the note on getServiceWorkerHref OneSignal developers left for the those who dare venture into their source code:

    else if (workerState === ServiceWorkerActiveState.Bypassed) {
      /*
        if the page is hard refreshed bypassing the cache, no service worker
        will control the page.
        It doesn't matter if we try to reinstall an existing worker; still no
        service worker will control the page after installation.
       */
      throw new InvalidStateError(InvalidStateReason.UnsupportedEnvironment);
    }

As you can see, the error is raised when the service worker has the "Bypassed" state. What is that, you may ask? Let's look at ServiceWorkerActiveState enumeration below, in the same file:

  /**
   * A service worker is active but not controlling the page. This can occur if
   * the page is hard-refreshed bypassing the cache, which also bypasses service
   * workers.
   */
  Bypassed = 'Bypassed',

It seems, when the browser "hard-refreshes" the page, it bypasses the service worker and OneSignal can't properly initialize when that happens. Hard-refresh can happen for a number of reasons — here are some of them (to the best of my knowledge):

  • if you click the refresh button a bunch of times (usually seconds consecutive refresh within a short period of time may trigger this)
  • if you have caching disabled in your DevTools
  • if the server sets a no-cache header

What is happening after a hard reset

I don't know exactly what you mean by "hard reset", but that sounds like it would trigger this issue. I would suggest you close your browser and then visit the page you are working on without using "reset" functions — theoretically, the service worker should be used for caching on consecutive visits and that would ensure OneSignal can function.

Related