angular: Service worker 6.x does not work correctly in Edge and Samsung Internet on Android

I’m submitting a…


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior

App with service worker loads fine the first time in Chrome 56 (And Edge Android, Samsung Internet). If you reload the page, the app fails with:

ERR_FAILED

Uncaught (in promise) DOMException: Failed to execute 'waitUntil' on 'ExtendableEvent': The event handler is already finished. at Driver.handleFetch (http://127.0.0.1:8887/ngsw-worker.js:1941:15) handleFetch @ ngsw-worker.js:1941

Expected behavior

Service worker enabled sites should work correctly on Chrome 56, Edge and Samsung Internet browsers

Minimal reproduction of the problem with instructions

ng new repro --service-worker ng build --prod Use Web server for Chrome or related to browse the dist folder.

What is the motivation / use case for changing the behavior?

Service worker should work correctly on all supported browsers.

Environment


Angular CLI: 1.6.0-rc.1
Node: 8.9.1
OS: win32 x64
Angular: 5.0.5
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router, service-worker

@angular/cli: 1.6.0-rc.1
@angular-devkit/build-optimizer: 0.0.34
@angular-devkit/core: 0.0.22
@angular-devkit/schematics: 0.0.38
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.9.0-rc.1
@schematics/angular: 0.1.8
typescript: 2.4.2
webpack: 3.8.1


Browser:
- [x] Chrome (desktop) version 56
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [x] Edge version  ANDROID 
 
For Tooling issues:
- Node version: v8.9.1  
- Platform:  Windows 

Others:

`
`

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 21
  • Comments: 51 (11 by maintainers)

Most upvoted comments

This all seems related to this Chromium bug fixed in v60: https://bugs.chromium.org/p/chromium/issues/detail?id=621440: could mean that any Angular app using Service workers will not work on browsers based on Chromium <60

I’ve tried the event.waitUntil polyfill mentioned in that issue (https://github.com/jakearchibald/async-waituntil-polyfill) and it solved the problem (tested on Samsung Internet 6 & 7 based on Chromium 56 & 59).

It’s pretty hacky, but you can simply take the {{host}}/ngsw-worker.js file, add the polyfill in it, rename it to ngsw-worker-polyfill.js and place this file in src. Then in .angular-cli.json under assets add:

{
  "glob": "ngsw-worker-polyfill.js",
  "input": "./",
  "output": "./"
}

This will export your custom worker file in dist when building your app. Then in app.module.ts change the ServiceWorkerModule import so that it registers your polyfilled worker file instead of the one from @angular/service-worker package: ServiceWorkerModule.register('/ngsw-worker-polyfill.js', {enabled: environment.production})

This is just a temporary fix, and in case you upgrade package versions you’ll have to manually update this worker file with the latest code.

@alxhub Is adding this polyfill to the @angular/service-worker package something the Angular team would consider?

Hello, I found some problem on latest version of Samsung Internet (6.2.01.12) and Angular5 service worker as described here. I have a strange behavior: 1- first access ok 2- refresh: “website unvailable” message

If I… delete cookies (and only cookies) on the website, and I refresh: it’s ok, the app work… untill the next refresh.

So maybe it’s linked.

And I didnt have a bug on previous Samsung Internet version.

I’ve been trying to investigate this issue, as I have found no workaround yet other than disabling service workers in my app (which I want to avoid as much as possible)

Bug is present on both current Samsung Internet browser (6.4.10.5) and their beta (7.2.10.28), which are based respectively on Chromium 56.0.2924.87 and 59.0.3071.125

I have not experienced the bug on Edge Android (1.0.0.1921) which seems based on a more recent Chromium version (65.0.3325.109)

An example anyone can reproduce with the Angular Material docs site: https://material.angular.io, which uses @angular/service-worker: 6.0.0-rc.5:

On page load the error displayed by the service worker is: Uncaught (in promise) InvalidStateError: Failed to execute 'waitUntil' on 'ExtendableEvent': The event handler is already finished. (ngsw-worker.js:1981) which comes from https://github.com/angular/angular/blob/master/packages/service-worker/worker/src/driver.ts#L407

Future navigations in the app trigger the same error coming from https://github.com/angular/angular/blob/master/packages/service-worker/worker/src/driver.ts#L399 this time: Uncaught (in promise) InvalidStateError: Failed to execute 'waitUntil' on 'ExtendableEvent': The event handler is already finished. (ngsw-worker.js:1974)

At this point I’m not sure whether this is a @angular/service-worker or Chromium issue? I’ll follow up if I find anything new, after I learn more about the logic behind service workers

Seeing the error on Chrome 56.0.2924.76 (64-bit) on Mac as well!

Is there any progress? This is definitely a blocker for service worker and PWA support on prodution!

@juliencap

  1. Create a new ngsw-worker-polyfill.js file in src folder
  2. Take the content of your ngsw-worker.js file in the dist folder, and copy-paste the polyfill at the beginning of function(): see exemple here in this gist
  3. Make ServiceWorkerModule register your polyfill worker instead of the regular worker in app.module.ts: ServiceWorkerModule.register('/ngsw-worker-polyfill.js', {enabled: environment.production})
  4. It seems like you’re using Angular 6.0.0 and the new version of the angular-cli.json file. assets is the right place, but the paths for input and output need to be slightly modified compared to 5.x.x:
{
       "glob": "ngsw-worker-polyfill.js",
        "input": "src",
        "output": "/"
}

Experiencing this same bug on Samsung Internet browser (6.4.10.5)

angular-cli: 1.6.3 angular/service-worker: 5.1.2

First page load is fine, then I refresh and get a “This site can’t be reached” error page. Cleaning Cookies and site data then reload fixes the issue, until the next page refresh.

Any updates on this issue? Do we know when it’s gonna be fixed? I am still experiencing it on Chrome 59 and angular cli 1.7.3.

@gkalpak this looks like something we should take on. Maybe ship our own version of the polyfill?

Is this likely to ever be fixed or do I need to find a different way to add a service worker, I’d like to be able to add a service worker to my site but it’s not possible if it breaks the site on some browsers.

@alxhub any updates regarding this issue?

Oh, yes I knew the new beta works, but that doesn’t help us wanting to support the other devices. Since I wanted firebase messaging support, just register it with your own file like so:

ServiceWorkerModule.register("/sw.js")

Then in sw.js:

try {
  importScripts("/ngsw-worker.js");
} catch (ex) {
} // Try, Catch //

// Firebase stuff //

Normally I’d just include ngsw-worker, and if it’s in debug mode, it’ll just raise an exception when it can’t include the file (so I just catch it), and in production it’ll include it when it’s there… Well, normally. Right now I just have it commented out until this bug is sorted out.

Same problem here: @angular/cli: 1.7.4 @angular/service-worker: ^5.2.10 Samsung Internet: Version 7.0.10.46

I wouldn’t mind if the service worker just doesn’t work on Chromium < 60. But crashing the whole app is a real deal breaker.

Thx @vleput for getting to the bottom of this ❤️ I am not sure there is much point in including the polyfill by default (since it only affects old versions of Chromium), but maybe we could:

a. Distribute two versions of the worker script (one with and one without the polyfill) or b. Make it possible to include extra scripts in the worker script via the cli (e.g. there could be a config option in angular.json to specify an extra script file (similar to polyfills.ts but for ngsw-worker.js). Or it could be a list of JS scripts to be imported (using importScripts(...)) at the top of ngsw-worker.js.

@alxhub, wdyt?

Thanks, I will continue on that tomorow!

(PS: On this project (I am using 5.2.10 and Angular CLI 1.7.4)

Final edit: works perfectly now. Thanks again 😃

Experiencing the same with angular-cli: 1.7.4 and angular/serviceworker: 5.2.10 on:

Mobile Safari UIWebView 7.1.2 Mobile Facebook browser 86.0.0 Chrome Mobile 37.0.0 with Android 5.0.1 Chrome Mobile 30.0.0 with Android 4.4.2

In these tested browsers and device the page never loads, any solution?.

I having the same issue with angular service worker 5.2.5 on Samsung Internet Browser and get the following error…

Uncaught (in promise) InvalidStateError: Failed to execute ‘waitUntil’ on ‘ExtendableEvent’: The event handler is already finished.

and the site doesn’t load properly. If I delete the service worker it then loads ok but on the next page refresh it’s broken again.

Chrome and Firefox on the same phone work fine.

To recap (for future reference):

  • This is caused by missing features in order versions of some browsers (e.g. older versions of Chrome, Edge, Samsung Internet, etc.).
  • The workaround is to enhance the ServiceWorker script with some polyfill, but doing so is not very straight forward for @angular/service-worker.
  • The problem and the workaround are explained in more detail in https://github.com/angular/angular/issues/20756#issuecomment-386236004.

If anyone wants to take it on, the possible fixes are:

  • Make it possible/easy to include extra scripts in the worker script via the cli; e.g. there could be a config option in angular.json to specify an extra script file (similar to polyfills.ts but for ngsw-worker.js). Or it could be a list of JS scripts to be imported (using importScripts(...)) at the top of ngsw-worker.js.
    • PROS: Flexible. Only those who need it pay the extra size cost.
    • CONS: Still requires some work from the developer. Not very easy to discover the problem/fix.
  • Embed our own version of the polyfill in the ngsw-worker.js script.
    • PROS: Works automatically.
    • CONS: Everyone pays the extra size cost (even if they don’t need the polyfill).

Same problem here, app crashing in samsung browser

Is there a way to deactivate service worker instead of crashing the entire app? Thanks

@mlc-mlapis it might be, but current versions of Android’s Samsung Internet & Edge USE older versions of Chrome and both of these browsers DON’T work…