I am confused about GCM Sender ID and API key. I'm responsible for building 3rd party server that will send notifications to Android app.
Which one do I have to store on server side? API key or Sender ID? Who is responsible for creating both, Android developer or me?
I've kinda figured it out on my own:
API key is generated on console and is used by 3rd party server to authenticate/authorize with GCM.
Sender ID is used by Android app to register a physical device with GCM to be able to receive notifications from GCM from particular 3rd party server.
Registration ID is a result of registration of physical device to GCM with Sender ID.
It depends on how your thirds party server is going to work, but in general it works like this:
The app sends one or more sender Ids which are Google Project Numbers to the GCM servers.
GCM returns a registration Id, which the app uses to register with the server.
The server uses the registration Id and the API key to send a message to the device via GCM.
When sending the message GCM will ensure that the Google Project Number and API key match and match what was used to create the registration Id. If they do it sends the message.
Information on how the developers get this information can be found in the GCM documentation: http://developer.android.com/google/gcm/gs.html
Depending on your needs there are third party commercial sever solutions available.
There are two keys or IDs on which GCM process rests upon. One is registrationID that is created at Android application side and sent to the Server application where API Key already stored. Message is push to the device using a combination of registration Id and API Key.
The regisration ID is generated by GCM servers when android application makes request to them. Keeping the already created project ID (at Google dev console).
GCM sender ID might also refer to this:
source: https://firebase.google.com/docs/cloud-messaging/js/client
Related
From a best practices standpoint, should you create a new Sender ID / Server Key per app/project that you want to incorporate FCM on?
I am using OneSignal to send Push Notifications to my apps, and I am setting up my Android use, and if I had multiple apps if there was any benefits/drawbacks to having them all under one project with the same Sender ID and using the same server keys?
yes, you can connect more than one app in one signal using one information (Sender ID / Server Key) from firebase ...
On this page they explain Web Push with Service Workers stating
Chrome currently uses Firebase Cloud Messaging (FCM) as its push service. FCM recently adopted the Web Push protocol. and then explaining Firebase and so on...
Since the Service Worker gives me a unique endpoint and a pubkey, it seems to me that technically it should be possible to use that endpoint directly, without anything additionally - except if Google deliberally forces a registration.
I mean, just send a POST request to that endpoint, sending just the notification data encrypted/authenticated using the pubkey without any "VAPID".
Do I absolutely need a Firebase account or is it possible to access the endpoint directly (without additional registration) if I just want to send a notification to a single device?
It's 2021 and all major browsers implement a push service and support VAPID now. You use a web push library (Javascript, Python, C#,..) of choice.
There is no need to register anywhere.
The technical mechanism in short is this:
You generate two VAPID keys once using the push library. One key is private and one is public.
The public key is used in the javascript as "application server key" when subscribing to the push service of the browser.
If the subscription is successful you receive a subscription object from the browser containing an endpoint and two additional keys.
The endpoint is an address depending on the web browser / manufacturer and the service it is currently using. The endpoints look like (Oct 2021) e.g.
Google Chrome h_tt_ps://fcm.googleapis.com/fcm/send/cz9gl....., Microsoft Edge h_tt_ps://wns2-par02p.notify.windows.com/w/?toke....., Mozilla Firefox h_tt_ps://updates.push.services.mozilla.com/wpush/v2/gAAAAABhaUA....
If your server program has this information (endpoint and keys from subscription object) it can send a push message to the endpoint with the push library. The corresponding service in the web, hosted by the manufacturer sends this to the browser's service on the device.
There is the PushAPI which shall get used.
But it doesn't is supported by every Browser at the moment.
You can find nice examples in the Service Worker Cookbook of Mozilla
I've been implementing Notification Channels in my android app to support recent android versions.
You can set the notification channel id when sending messages from the firebase web console, but I was not able to find out how to set the channel id when sending messages via fcm rest api.
Notification channels are not mentioned in the reference (https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages), but I am pretty sure there must be a way to set the channel id.
The key name I was missing is android_channel_id
I found the key name in the Legacy HTTP Server Protocol docs (https://firebase.google.com/docs/cloud-messaging/http-server-ref)
As part of our solution, we want to deploy an FCM "app server" at each of our customer sites. Each customer site has their own users with their own devices using our app. However, we want to make sure that if one of the customer sites is compromised, an attacker could not abuse the FCM "app server" (e.g. by sending notifications to all devices at all customer sites).
Instead of sharing credentials between all customer sites, we are thinking of generating a unique server key for each customer site. That way if one customer site is compromised, we can disable that server key and stop any more FCM notifications from being sent.
Question: Can we be sure that an attacker cannot send global notifications to all devices?
Assuming an attacker has a server key and access to one customer site "app-server", can they get a list of all the registered devices?
Is there a default notification "topic" that is sent to all devices? (e.g. /topic/all or /topic/global). If so, can we disable that default topic?
Instead of sharing credentials between all customer sites, we are thinking of generating a unique server key for each customer site. That way if one customer site is compromised, we can disable that server key and stop any more FCM notifications from being sent.
If by "we are thinking of generating a unique server key for each customer site" you mean that you'll simply create a Firebase Project for each customer site, then I think this is the correct approach.
Can we be sure that an attacker cannot send global notifications to all devices?
An app can receive messages from a different Sender by implementing the getToken(authorizedEntity, scope) which will generate a different token for each Sender. In order to negate this action, you could simply call deleteToken(authorizedEntity, scope) (my reference).
This would invalidate the token for that corresponding sender (which is what they probably have and should be the only one on their App Server), which would automatically disable them for receiving messages to your App.
So as long as you're able to remove them as a valid sender from your app, then it's all good.
Assuming an attacker has a server key and access to one customer site "app-server", can they get a list of all the registered devices?
This depends on how the App Server is implemented. If the customer's App server is only used for sending messages, but the tokens are stored elsewhere, then probably no. There is no API to retrieve registration tokens on the server side for an App based on the Server Key (see #1 here).
Is there a default notification "topic" that sends to all devices? (e.g. /topic/all or /topic/global). If so, can we disable that default topic?
There isn't. There is the option to send a Notification to a specific app via the Firebase Notifications Console, but if the app doesn't authorize the Sender ID corresponding to that project, it won't receive any messages from it. I've tested this behavior out before posting, so I'm positive that this is how it works.
There is no way to restrict a server key to only allow certain topics/devices/etc.
I would consider using Cloud Functions for Firebase to solve this a different way. You could build an HTTPS function that took per-site authorization tokens (by any means you deem fit) and then that function calls through to Firebase Cloud Messaging to actually send the push notifications.
This way, you have complete control over what kinds of push notifications can be sent by the "client" sites, and you don't have to worry about cascading security problems in the event a client site gets compromised.
To use the Google Cloud Messaging (GCM) service, you need to know the registration ID of the device. The registration ID is created if the Android app uses the GCM client to register itself. Is it possible for a server which sends GCM messages to get a list of all registration IDs for a certain app, or do the apps have to send their IDs to the server (during login for instance) ? If yes, is it possible to get a list of all device tokens for all installed iPhone apps to send Apple Push Notifications (APN) as well?
No, there is no way to get that list of registration IDs from Google nor that list of device tokens from Apple. Your app must send them to your server and your server must maintain that list.