angular: Service worker requestSubscription() freezes and doesn't show native popup if serviceworker.controller is null
๐ bug report
Affected Package
Is this a regression?
No
Description
The problem is here
https://github.com/angular/angular/blob/a06824aef6e2e1c5b1c037d2c2e1dda544842000/packages/service-worker/src/low_level.ts#L74-L82
When controllerchange
is triggered, the code access to serviceworker.controller
and filters it if is null
. After that, the registration
is created from the previous pipes.
What happens if the serviceworker.controller
is null
in all controllerchange
events? (At the moment you are thinking that couldnโt happen, but yes ๐it happens!!!๐.
Then if the app is started with serviceworker.controller = null
and requestSubscription
is called a few minutes later, the promise wonโt never be resolved.
https://github.com/angular/angular/blob/c0757d1d440d6f934436418add9755e7d630bbcf/packages/service-worker/src/push.ts#L93-L99
Possible solution
Merging registration
observable with serviceworker.ready
but Iโm not sure if breaks something.
https://github.com/angular/angular/blob/c0757d1d440d6f934436418add9755e7d630bbcf/packages/service-worker/src/low_level.ts#L81-L82
๐ฌ Minimal Reproduction
The problem reproduction is explained in the previous section. But if you want to get crazy to Chrome to test the bug, you can do the following:
You can test this on Chrome 72 Windows, the steps are not going to work on Chrome Mac. But I have logs that prove the bug happens in other Chrome version and platforms, maybe, doing different steps, but the state is the same, serviceworker.controller
is null
.
Steps Chrome Windows.
- Create a app with a checkbox or switch button to activate/descativate notifications.
- Check the switch in your app will call
requestSubscription()
- When the popup is shown, press Block.
- Go to de addressbar, click in the lock ๐. Change the notifications state to Allow. Chrome will say you that the page should be reloaded.
- Reload the page.
- If you call
requestSubscription()
again, you wonโt get the popup. Or if you write in the consoleserviceworker.controller
you will getnull
.
Here is an example image. The app is started, serviceworker.controller
is null
, but I can get the service worker registration and the push subscription, so serviceworker.controller
is not needed to get it. (Keys are hidden in the image).
๐ Your Environment
Angular Version: Tested in angular 7.1.7 but I think all version are affected.
Anything else relevant?
I use this code with a timeout before I run into the issue to avoid freezing the function. Iโm getting logs Can't subscribe: Timeout ocurred
from Chrome Windows but specially lots of entries for Chrome android.
this.swPush.requestSubscription({serverPublicKey: this.VAPID_PUBLIC_KEY}))
.pipe(
timeout(8000),
tap({
next: () => this.measuringDao.sendBackendEvent('activated_notifications').subscribe(),
error: err => this.logger.warn('Can\'t subscribe: ' + err.toString(), err)
}),
switchMap(sub => this.notificationsDao.registerPushSubscriber(sub))
);
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 1
- Comments: 16 (12 by maintainers)
From what I can tell, this is either a Chrome bug or if it is in Angular we donโt have a reliable reproduction. Thus this is issue is not actionable in its current state.
If you are still running into this problem and you have confirmed that this is not browser bug, please open a new issue with a minimal reproduction.
Not sure if same issue. I make the same call
navigator.serviceWorker.controller
isnull
.Can I help investigate? Should I create a separate issue?