Migration from GCM (manifest) to VAPID (applicationServerKey) managed incorrectly
Reported by
collimar...@gmail.com,
Feb 15 2017
|
|||
Issue descriptionSteps to reproduce the problem: 1. Subscribe a device by using GCM (you enter the GCM sender ID in the manifest.json) - notifications are sent successfully 2. Then you decide to migrate your application to VAPID, so you add an applicationServerKey param to the pushManager.subscribe call (and you leave the manifest there) 3. Subscribe a new device with VAPID - notifications are sent successfully 4. Take the initial device, which already has a subscription created with GCM - notifications are still sent successfully with the legacy GCM credentials 5. The problem is that if you call pushManager.subscribe on the initial device, it returns an FCM subscription (https://fcm.googleapis.com/fcm/send/...) that doesn't work - the error 400 UnauthorizedRegistration is returned by FCM to the server, as if you were using a wrong VAPID key pair 6. Moreover pushManager.getSubscription() still returns the old https://android.googleapis.com/... endpoint, while the pushManager.subscribe method returns the new FCM endpoint - that is clearly inconsistent behavior What is the expected behavior? Chrome on Android (like Chrome on Desktop and Firefox already do) must raise an error if pushManager.subscribe is called when there is already a subscription associated to a different sender (e.g. a different VAPID key or a legacy GCM sender). What went wrong? 1. pushManager.subscribe returns a new endpoint that doesn't work, but it should have raised an exception 2. pushManager.subscribe and pushManager.getSubscription() return two different endpoints (you can call them many times, with interleaving, and they will keep returning different endpoints - that is inconsistent) Did this work before? N/A Does this work in other browsers? Yes Chrome version: 55.0.2883.91 Channel: n/a OS Version: 6.0.0, HUAWEI Flash Version:
,
Feb 15 2017
Hi Marco, thanks for the report! According to the bug you're using Chrome 55 - we actually fixed the first part of this issue in Chrome 56 ( Issue 638924 ). Would you mind trying again with the latest version? The difficulty in determining which URL we return is that it's based off whether you pass an `applicationServerKey` or not. The reason for this is that many developers, unfortunately, were (and are) parsing the URL under the assumption that it would be the GCM endpoint. However, they should be interchangeable. Does the authentication error occur because this triggers your server to try and authenticate using VAPID, as opposed to the GCM authentication secret? One possible work-around (that I haven't tried!) would be to get the subscription and read the PushSubscription.`options` object to see whether the applicationServerKey was set.
,
Feb 15 2017
> Would you mind trying again with the latest version? Chrome 56 is not available yet on the Play Store (Italy). I'll try to update Chrome again in the next days. > Does the authentication error occur because this triggers your server to try and authenticate using VAPID, as opposed to the GCM authentication secret? Yes, the problem is that our server uses VAPID for fcm.googleapis.com, while it uses the legacy GCM HTTP server for old subscriptions (android.googleapis.com). This is **the correct behavior** based on what you have wrote on your blog: > To subscribe a Chrome user for push with the VAPID public key, you need to [...] You'll know if it has worked by examining the endpoint in the resulting subscription object, if the origin is fcm.googleapis.com, it's working. > https://developers.google.com/web/updates/2016/07/web-push-interop-wins
,
Feb 15 2017
What behavior should I expect from **Chrome 56**? I mean: After raising the exception, if you catch it and call pushManager.getSubscription (like we do on line 145: https://pushpad.xyz/pushpad.js), do you get the correct GCM endpoint (android.googleapis.com) or you get the corrupted endpoint that starts with fcm.googleapis.com?
,
Feb 15 2017
I see that the release has been delayed indeed, it should become available in the next few days. The documentation indeed doesn't cover this case very well. We'll have to update the article in the near future due to new syntax for VAPID (that other browsers are also adopting), so this'll be considered as part of that. Chrome 56 will start throwing when calling subscribe() because the given `applicationServerKey` is different from the Manifest's `gcm_sender_id` that was used to create the subscription. Given that getSubscription() will return the existing subscription, that should indeed return the endpoint you expect.
,
Feb 16 2017
> Chrome 56 will start throwing when calling subscribe() because the given `applicationServerKey` is different from the Manifest's `gcm_sender_id` that was used to create the subscription. Given that getSubscription() will return the existing subscription, that should indeed return the endpoint you expect. Ok great! This is the behavior that I was expecting because we had tested the migration from GCM to VAPID on Chrome 56 Desktop. So if the behavior will become consistent on the mobile version the issue will eventually solve. > The documentation indeed doesn't cover this case very well. We'll have to update the article in the near future due to new syntax for VAPID (that other browsers are also adopting), so this'll be considered as part of that. I think that with the new behavior of Chrome 56, you can suggest to use the method that we have already used and successfully tested (on desktop) at Pushpad: If you call pushManager.subscribe and it raises an exception, catch the exception and, in order to establish if the current device is subscribed to push notifications with another sender, call pushManager.getSubscription. You can see the code on line 145: https://pushpad.xyz/pushpad.js This method ensures that: - old GCM subscriptions work - new VAPID subscriptions work - if you try to subscribe with VAPID an old GCM subscription, then you still get the old GCM subscription - after an old GCM subscriber resets the permission, he will be able to use VAPID
,
Feb 16 2017
That's very helpful, thank you! +mattgaunt FYI Let me close this issue as there's nothing we can change about Chrome 55 anymore. Please feel free to file a new issue for other issues you're encountering.
,
Feb 21 2017
I have just tested with Chrome 56 on Android and the method I've described above works as expected! |
|||
►
Sign in to add a comment |
|||
Comment 1 by collimar...@gmail.com
, Feb 15 2017Even removing the manifest.json doesn't solve the problem - the issue is still the same. Even calling pushManager.subscribe({ ... }).then(function() { pushManager.getSubscription ... }); doesn't circumvent the problem: we still get the invalid FCM endpoint, returned by getSubscription this time. However if we call pushManager.getSubscription outside the pushManager.subscribe callback, we get the old GCM endpoint. This is totally inconsistent behavior. Because of this bug at Pushpad we're getting a lot of FCM endpoints that are invalid (400 UnauthorizedRegistration)! We can't do anything to prevent that on our side. Please do something to fix this bug.