Closed
Bug 1371067
Opened 7 years ago
Closed 4 years ago
PushManager subscribe() automatically failing with NotAllowedError when permission state is prompt
Categories
(Core :: DOM: Push Subscriptions, defect, P3)
Tracking
()
RESOLVED
WORKSFORME
People
(Reporter: bhhronik, Unassigned)
Details
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Steps to reproduce: Within service worker code I have the following snippet: ``` self.registration.pushManager.permissionState() .then(function(state) { if (state === 'prompt') { self.registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: applicationServerKey }) .then(function(newsubscription) { console.log("sending new subscription"); // ... send subscription info to server }) .catch(function(err) { console.warn('Failed to subscribe the user: ', err); }); } console.log(state); });``` Firefox version: 53.03 OS Version: 10.11.6 Actual results: self.registration.pushManager.permissionState() consistently returns 'prompt', so the call to self.registration.pushManager.subscribe(...) should prompt the user to enable notifications. However, it automatically errors with "NotAllowedError: User denied permission to use the Push API." Expected results: I would expect the above error to occur only if the permission state was 'denied', however for a permission state of 'prompt' I would expect the prompt to occur asking a user if they would like to allow or disallow notifications.
Updated•7 years ago
|
Component: Untriaged → DOM: Push Notifications
Product: Firefox → Core
Confirmed that same behavior exists on the newest nightly build as well as the newest beta release.
To support my expectation, from steps 8 and 9 outlining the PushManger's subscribe method, taken from the w3c Editor's draft(https://w3c.github.io/push-api/#dom-pushmanager): """ 8.Ask the user whether they allow the webapp to receive push messages, unless a prearranged trust relationship applies or the user has already granted or denied permission explicitly for this webapp. 9. If not granted, reject promise with a DOMException whose name is "NotAllowedError" and terminate these steps. """ Unless I'm mistaken, the permission state of 'prompt' should signal that user has not already granted or denied permission explicitly for the webapp.
Comment 4•7 years ago
|
||
Hi Brent, thanks for the report! I suspect this will end up as a WONTFIX. It's not possible to ask for permission from within the service worker: permission doorhangers are always associated with a window, but there might not be any controlled windows open when the worker runs...and showing a disembodied doorhanger would make for a confusing UX. Could I ask why you're checking the permission in the service worker? Is this in a `pushsubscriptionchange` event handler, or somewhere different? (IIRC, if the user revokes the permission, we won't fire `pushsubscriptionchange` until the permission is granted again, because the worker can't resubscribe). Given that you can't prompt, I think you could remove the check and let the `subscribe` call fail, but I'm missing the full context of where that snippet is called.
Flags: needinfo?(kit) → needinfo?(bhhronik)
Hi Kit, thanks for the response! The reason why I'm asking for permission from within the ServiceWorker is so that I can ask for permission in response to a message(which could be sent from multiple locations, settings page, banner popups, etc) being sent to the ServiceWorker. A more complete snippet on the service worker side would look something like(more going on certainly, but sharing the parts that convey the idea): ``` self.addEventListener('message', function(event){ var message = JSON.parse(event.data); if ("enable" in message) { console.log("service worker enabling notification"); enableBrowserNotifications(); } }); function enableBrowserNotifications() { self.registration.pushManager.permissionState() .then(function(state) { if (state === 'prompt') { self.registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: applicationServerKey }) .then(function(newsubscription) { console.log("sending new subscription"); // ... send subscription info to server }) .catch(function(err) { console.warn('Failed to subscribe the user: ', err); }); } console.log(state); }); } ```
Flags: needinfo?(bhhronik)
Updated•7 years ago
|
Priority: -- → P3
Hey Kit, Any update on this? It isn't immediately obvious to me how we would be able to create a subscription in response to a message sent to a ServiceWorker without being able to create a subscription from the ServiceWorker. Thanks!
Comment 7•7 years ago
|
||
(In reply to Brent from comment #6) > Any update on this? It isn't immediately obvious to me how we would be able > to create a subscription in response to a message sent to a ServiceWorker > without being able to create a subscription from the ServiceWorker. Sadly, I don't think this will work. Since the worker can run in the background, when none of the site's windows are open, there's nowhere that we can show the permission doorhanger. You'll need to call `pushManager.subscribe` when you call `navigator.serviceWorker.register`. Martin, should we add a non-normative note to the spec that workers can't ask for permission? Or is this supposed to work? FWIW, I tried this in Chrome, and saw the same behavior. Calling `registration.pushManager.subscribe` from the main page shows the doorhanger. OTOH, registering a service worker, sending a message via `postMessage`, and calling `self.registration.pushManager.subscribe` from the worker's `onmessage` handler rejects with "DOMException: Registration failed - permission denied". Are you seeing different results in Chrome, Brent?
Flags: needinfo?(martin.thomson)
Hi Kit, Thanks for the response! Yeah, I was able to get around by doing something like this(instead of sending the message to the push subscription): ``` navigator.serviceWorker.ready.then(function (registration) { const applicationServerKey = urlBase64ToUint8Array(applicationServerPublicKey); registration.pushManager.getSubscription().then(function (subscription) { // Do stuff }); }); ``` I'm actually running into issues on Chrome on the sending side(receiving 400 instead of 201 which I'm receiving from Firefox). Would you happen to know if Chrome and Firefox handle VAPID(conforming to the v02 spec) in subtly different ways?
Comment 9•7 years ago
|
||
Kit, https://github.com/w3c/push-api/issues/260
Flags: needinfo?(martin.thomson)
Comment 10•4 years ago
|
||
:annevk, am I interpreting correctly that https://github.com/w3c/push-api/commit/d0b78c3b1266f5d045ab5cebf1fe7e454821f2fc suggests now a WORKSFORME ?
Flags: needinfo?(annevk)
Comment 11•4 years ago
|
||
Yeah, though I filed https://github.com/w3c/push-api/issues/322 to turn that into a normative requirement and get the specific exception defined as well. If that's not what we do here we might need a follow-up bug to change the exception.
Status: UNCONFIRMED → RESOLVED
Closed: 4 years ago
Flags: needinfo?(annevk)
Resolution: --- → WORKSFORME
You need to log in
before you can comment on or make changes to this bug.
Description
•