angular: Service worker requestSubscription() freezes and doesn't show native popup if serviceworker.controller is null

๐Ÿž bug report

Affected Package

@angular/service-worker

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 registrationobservable with serviceworker.readybut 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.

  1. Create a app with a checkbox or switch button to activate/descativate notifications.
  2. Check the switch in your app will call requestSubscription()
  3. When the popup is shown, press Block.
  4. Go to de addressbar, click in the lock ๐Ÿ”’. Change the notifications state to Allow. Chrome will say you that the page should be reloaded.
  5. Reload the page.
  6. If you call requestSubscription()again, you wonโ€™t get the popup. Or if you write in the console serviceworker.controller you will get null.

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). captura de pantalla 2019-03-01 a las 19 49 21

๐ŸŒ 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)

Most upvoted comments

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

await this.swPush.requestSubscription({ serverPublicKey })
  • I get no response, error or otherwise.
  • navigator.serviceWorker.controller is null.
  • Reproducible in Chrome and Firefox.

Can I help investigate? Should I create a separate issue?