web-push-libs / pywebpush

Python Webpush Data encryption library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unable to send notification to chrome with data.

akoidan opened this issue · comments

I'm trying to send push notification that contains some data to chrome using FCM.

I'm using firebase console and credentials copied from it to generate a push notification
image

The chrome code looks like this:
manifest.json:

{
  "name": "PyChat Push Notification",
  "short_name": "PyPush",
  "start_url": "/",
  "display": "standalone",
  "gcm_sender_id": "620421656154"
}

sw.js:

self.addEventListener('push', (e: any) => e.waitUntil(getPlayBack(e)));

main.js:

await webpackServiceWorker.register( {scope: '/'}) ;
let subscription = await this.serviceWorkerRegistration.pushManager.subscribe({userVisibleOnly: true});
sendToServer( subscription.toJSON())

I can successfully send a push notification W/O any data using

from pywebpush import webpush, WebPusher
WebPusher(registration_id_from_browser).send("asd", gcm_key=server_key_from_image_above)

WIth the current method, in the data field in event is null on service worker. If I understood correctly this data needs to be encrypted using VAPID otherwise firebase replaces it with null. So my attempt looks like this:

vapid_data = {'privateKey': 'COPIED_PRIVATE_KEY_FROM_FIREBASE_MAGE_ABOVE', 'publicKey': 'COPIED_PUBLIC_KEY_FROM_IMAGE_ABOVE'}
webpush(
    registration_id_from_the_browser,
    'Your Push Payload Text',
    vapid_private_key=vapid_data['privateKey'],
    vapid_claims={"sub": "mailto:deathangel908@gmail.com", 'aud': 'https://fcm.googleapis.com'}
 )

But i'm getting

Response body:the key in the authorization header does not correspond to the sender ID used to subscribe this user. Please ensure you are using the correct sender ID and server Key from the Firebase console.

I also tried to put server_key copied from firebase console (the image) but the error is still the same.

I feel kinda confused at the end of the day since I read a lot of topics like this and this and this and this and this and this and also using PyFCM library and nothing seems to work.

Could someone please clarify:

  • is FCM and GCM are the same?
  • If google announced that GCM are no longer supported a few years ago, why my FCM messages still work w/o data, as I use gcm_sender_id in manifest.json.
  • If vapid is required to send push messages, Should I copy private key form FCM console or generate by itself?
  • If FCM server_key is no required to send push notification, does this means that everyone who knows user_subscription_id can send a push notification to the end user via my FCM account?
  • How can I send notification with data to chrome device. Is FCM the only option? Also I would not like use google libraries on the client to get push notifications since they are really heavy.

As I understand, GCM was retired around two years ago. I believe that they may still honor some GCM senderids that were created before the cutoff, but they strongly encourage folk to switch to using FCM.

There are several different "types" of webpush messages. Data free messages don't have many of the same requirements as messages with data (e.g. they don't require encryption headers if using older content encoding formats.) It may be that FCM is more permissive.

I can't speak to all of the requirements that FCM may have, but I do know that Google is far stricter about authorization than other providers. VAPID is required, for instance, and FCM publishes info on how to authorize requests. Normally, you (the publisher) should own the VAPID key and only include the public half when registering an endpoint. You use the private half when signing the claim set you include as the authorization header. Often this is done for you by whatever library your using, pywebpush uses py-vapid for that.

I do know that it's important that the credentials match for both the remote app (in the case of FCM messages to the device) and the server. I've frequently mixed those up by accident in the past. You might also want to look over the Service Account help page. That said, I'll note that it is not possible to write to an endpoint that you don't have a VAPID key for, or don't have the decryption credentials (which are provided during the initial subscription request). In fact, it's worth noting that the VAPID key needs to be the same for any subscription that you've registered it with, so it's critical that you both keep that key safe, and don't use the wrong or different key when signing the VAPID claims.

Finally, you have to use FCM libraries on android. That's not necessarily a bad thing. Notifications require keeping a connection open to the server. This can be battery intensive, and Google has worked that bit low enough into the kernel that it's very power efficient, far more than anything you can do at the app level.

I'm not really sure that this is a pywebpush issue per se, since you note that you're having problems with other systems as well. Is there some issue you're having with pywebpush specifically?

@jrconlin thanks a lot for clarifications. That really explained a lot!. As I understand this library provides an API to send push notification to a browser based on this README

In the browser, the promise handler for registration.pushManager.subscribe() returns a PushSubscription object. This object has a .toJSON() method that will return a JSON object that contains all the info we need to encrypt and push data.

From what I understand chrome is the most used browser atm and pywebpush provides an abstraction on its API for the server side to send notification to.

Is there an end-to-end guide to for wending push notification using chrome and pywebpush? It seems to me that webpush provides a unit API to send an abstract data notification with any service, but it does say anything about real integration with provides like firefox or chrome which makes life a bit difficult.

I'd be kind of surprised if there were end-to-end guides for pywebpush and chrome, but there may be some out there somewhere. I wrote this library principally so I could test Autopush. A nice bonus is that it could be useful for others (because, Yay! Standards!), but I also fully expected someone to write up a better library in the future, and again, I suspect there may be ones out there that are. There are a LOT of reasons you probably don't want to use this library at any sort of scale. It's fine for small projects or sites with low-ish numbers, but it's absolutely not optimized to do thousands or millions of transactions.

I've not really paid close attention to what Chrome does, because, to be frank, I don't care what Chrome does. I happily accept PRs that address specific issues around Chrome, so long as they don't break the RFC or how I can test our server.