Workbox: skipWaiting() fails to activate waiting service worker

Created on 6 Dec 2019  路  5Comments  路  Source: GoogleChrome/workbox

Library Affected:
workbox-core v4.3.1

Browser & Platform:
Windows: Google Chrome 78.0.3904.108, Firefox 71.0

Issue Description:
I've tried to follow the instructions at the docs to show a prompt, when an update is available.

After clicking the button that triggers wb.messageSW({type: 'SKIP_WAITING'});, the message is processed in the service worker, and skipWaiting() is called. Then, a warning is logged to console in chrome:
Event handler of 'install' event must be added on the initial evaluation of worker script.. The service worker

I've also tried to do a minimal reproduction of the bug, but there, it works as intended.
Any idea whats going wrong in my project?

workbox-core

Most helpful comment

As per the recipe, you need to make sure that your service worker includes

addEventListener('message', (event) => {
  if (event.data && event.data.type === 'SKIP_WAITING') {
    // Use this, and not workbox.skipWaiting()
    skipWaiting();
  }
});

and not workbox.skipWaiting() for that to work. (The skipWaiting() in that example is effectively self.skipWaiting(), and self refers to the ServiceWorkerGlobalScope.)

It's a subtle difference, but workbox.skipWaiting() wraps the call inside of an install handler, and while that's suitable for use outside of a message event listener, inside the listener it ends up being executed after the initial evaluation of the worker script.

All 5 comments

As per the recipe, you need to make sure that your service worker includes

addEventListener('message', (event) => {
  if (event.data && event.data.type === 'SKIP_WAITING') {
    // Use this, and not workbox.skipWaiting()
    skipWaiting();
  }
});

and not workbox.skipWaiting() for that to work. (The skipWaiting() in that example is effectively self.skipWaiting(), and self refers to the ServiceWorkerGlobalScope.)

It's a subtle difference, but workbox.skipWaiting() wraps the call inside of an install handler, and while that's suitable for use outside of a message event listener, inside the listener it ends up being executed after the initial evaluation of the worker script.

Thanks a lot for your reply. That worked!

I'm bundling my service worker with webpack, importing the functions from workbox-core. Having skipWaiting still in the import statement added to the confusion.

I was stuck on this too. Just to clarify it for people, removing this import { skipWaiting } from 'workbox-core'; got it working. You do not want to use that method, instead you will have an undefined function as it's called in the global scope.

addEventListener('message', event => {
    if (event.data && event.data.type === 'SKIP_WAITING') {
        console.log('skip waiting');
        // eslint-disable-next-line no-undef
        skipWaiting();
    }
});

@CalebKester sorry about that confusion. In v6, we've deprecated usage of skipWaiting() from workbox-core because of that sort of frustration.

https://github.com/GoogleChrome/workbox/blob/6d38919ebbc9664327e19ff00302d805c8166170/packages/workbox-core/src/skipWaiting.ts#L16-L33

Makes perfect sense once it got me understanding more how it works. Thanks for all the good work you guys do. Can't wait for v6!

Was this page helpful?
0 / 5 - 0 ratings