I’ve noticed that my service worker doesn’t respond to self.skipWaiting()
when there are still tasks to be run.
In my service worker’s fetch
event, I see various Firebase polls that use HTTP POST requests.
If I handle these requests in the service worker like so:
self.addEventListener("fetch", (event) => { if (event.request.method === "POST") { return event.respondWith(new Response(null, {status: 444})) } ... })
Then self.skipWaiting()
always works as expected.
However, if I do the following:
self.addEventListener("fetch", (event) => { if (event.request.method === "POST") { return event.respondWith(fetch(event.request)) } ... })
Then self.skipWaiting()
seems to have no effect. In Chrome’s devtools, the new service worker still isn’t active (and also clicking on the blue skipWaiting
link also has no effect).
As a result, it seems that I have to choose between ensuring that self.skipWaiting()
works, and allowing Firebase’s polling requests, but not both. Is there a way get self.skipWaiting()
to work while still allowing Firebase’s polling requests?
Advertisement
Answer
I don’t see from your code where you’re calling self.skipWaiting()
, but the main thing to know about that function is that it “flips” a flag and attempts to activate the waiting
service worker. I’m not sure which part of that sequence is not working as expected, and I’m also not sure if you’re describing something that happens just in Chrome or in other browsers as well. If you’re seeing unexpected behavior just in Chrome, filing a bug is probably your best bet.
That being said, in the interest of providing a workaround, I wanted to say that you don’t have to call event.respondWith()
inside of a fetch
event handler at all. If all your fetch
handlers complete without any of them calling fetchEvent.respondWith()
, then the default browser networking behavior will be used instead. So you could restructure your fetch
handler like the following, and perhaps work around the issue.
self.addEventListener("fetch", (event) => { if (event.request.method === 'POST') { return; } // Your non-POST response logic goes here. });