WICG / background-sync

A design and spec for ServiceWorker-based background synchronization
https://wicg.github.io/background-sync/spec/
Apache License 2.0
640 stars 85 forks source link

Allow use of Background Sync with the Push API (when no window is opened) #147

Open collimarco opened 5 years ago

collimarco commented 5 years ago

The Push API spec suggests to use Background Sync for pushsubscriptionchange. We would also like to use Background Sync for the reliable processing of push events.

However those events may be triggered when no window is opened and this causes an error in Chrome:

Uncaught (in promise) DOMException: Attempted to register a sync event without a window or registration tag too long.

Can you allow the usage of sync.register even when no window is opened?

h43z commented 5 years ago

Pushsubscriptionchange won't trigger when a service worker is not running. That event is not able to wake the sw up. It will trigger when the user visits the website again (maybe after the subscription was made invalid). I guess they mean only then you will also be able to use the sync api.

collimarco commented 5 years ago

Pushsubscriptionchange won't trigger when a service worker is not running.

Having that service working running is something different from having a window attached to it.

Example: a service worker wakes up for a push event and then also pushsubscriptionchange is triggered. Now my code tries to use sync.register and fails because there is no window attached.

h43z commented 5 years ago

Having that service working running is something different from having a window attached to it.

That is true.

Regarding your example. There won't be a push event fired if the subscription was made invalid before. With an invalid subscription you weren't able to push in the first place. Meaning the sw won't wake up to trigger pushsubchange.

collimarco commented 5 years ago

There won't be a push event fired if the subscription was made invalid before.

No, I think that there is a grace period during which the old subscription is still valid.

Also consider this:

  1. Subscription is valid and push occurs
  2. Service worker is now active
  3. pushsubscriptionchange is fired
  4. sync.register raises an error because there is no window attached...

Finally the service worker in the future will be activated in background for many different things and this will cause problems and random failures (difficult to debug!) if you can't always use sync.register.

h43z commented 5 years ago

No, I think that there is a grace period during which the old subscription is still valid.

I really don't think there is one but I could be wrong.

What you outline could in theory be possible I guess. But I think it's very unlikely that a push happens and in the next minute subscription changes.

I have no idea where this service worker thing is going I only started looking into it recently. I was actually trying to use sync.register without a window too. That's what led me here into this thread.

collimarco commented 5 years ago

it's very unlikely

It's very unlikely means "very difficult to debug" and "unreliable technology". Also note that the aim of sync is to create a reliable technology... otherwise you can just avoid to use sync and make network calls directly.

Also it is not so unlikely since I think that a grace period exists and that the subscription can be replaced now, when the browser is activated, even if the subscription had expired hours or days before.

h43z commented 5 years ago

I am not familiar with the spec where do you get it from that there is a grace period? And how would it work?

I only played with chrome and saw that if you unregister the subscription or the service worker you cannot push anymore to it.

collimarco commented 5 years ago

@h43z Sorry, we are going off topic here... you can check the spec for more information.

The point is that pushsubscriptionchange can be triggered:

In both cases the pushsubscriptionchange will be triggered and no website window is available... thus an error will be raised by sync.register. Since the Push API spec suggests to use it, this is clearly a bug.

jkarlin commented 5 years ago

sync.register isn't allowed when there is no client window in order to protect privacy. We don't want sync events to keep reregistering themselves forever when they're in the background.

collimarco commented 5 years ago

@jkarlin Ok, but then you should coordinate your thought with the people who is writing the Push API. It doesn't make sense that they suggest to do something that doesn't work. At least if you clearly reject this use case, they will have to find another solution for the Push API.

collimarco commented 5 years ago

This is really important... you don't know how many times subscription are lost due to subscription refresh + network failure. Basically you subscribe to a website and then after some time the notifications stop working, and the reason is related to this.

mohamedhafez commented 5 years ago

sync.register isn't allowed when there is no client window in order to protect privacy. We don't want sync events to keep reregistering themselves forever when they're in the background.

@jkarlin I think a good solution would be to only allow sync.register when there is no client window only if its being called from a onpushsubscriptionchange event handler. That way web developers are able to send the refreshed subscription info to the app server reliably (as is currently recommended by the Push API spec), and since the service worker doesn't control when onpushsubscriptionchange is triggered, it can't abuse the system by registering syncs forever in the background.

jkarlin commented 5 years ago

@beverloo who would know more than me about push and how sync should interact with it.

rasoulabbasi20n commented 2 months ago

Any idea that how should I send upstream messages from service worker via register-sync approach? The same error raised up when I tried to do it. @mohamedhafez if the security issue is the culprit here, then why is the sync-event even placed in service-workers?

codecracker2014 commented 2 months ago

This issue occurs for apps loaded inside an iframe too, regardless of whether the window is open or not.