While publishing the Android app, I created a blunder. I commented the code which used to fetch GCM registration ID and send it to our server for persistence. We do have the device ID of all the users, however, their GCM Registration ID is missing on our server side. Is there any way, by which I can register all my users and get their GCM registration ID from the server directly using their respective device ID?
Also, if anyone gives me the correct solution, a Beer treat is assured!
In short No. The GCM InstanceID token identifies an app on a device, so more than the device's ID would be needed to generate the token. Google Play Services on your client device is used to generate the application's InstanceID token. This token cannot be generated from the device ID.
Each app on a device should have a unique InstanceID token, being able to generate this externally from the device with known parameters could be a security issue.
Related
I am confused on relationship between registration id and tokens. In the tutorial for GCM from Google, we register for a registration id in the beginning. However, we also get a token. Now, in the diagrams, we send the registration id to the targeted server. However, do we also send the token? I know that the token is derived from the registration id. Is the token used as an authentication mechanism between GCM and the app and the server never knows about the token?
If you are looking for a basic knowledge about Google Cloud Messaging, IMO, you can refer to the following:
Basically, you need to do the steps:
Create a new project at Google Developers Console . At this
step, for simplicity, you just need to take note of 2 values: Project Number, which
will be used as SENDER_ID in the client project; and API server key (created at Credentials), which
will be used as API_KEY in the server project.
Create a new simple Android project for server side (with basic source code as my answer in the following links).
Create a new simple Android project for client side (with basic source code as my answer in the following links, I customized from the original source at Google Cloud Messaging - GitHub).
Run the client app, you will get the registration token (means that your device has successfully registered). Then, paste (hard-code) this token at CLIENT_REGISTRATION_TOKEN variable in server app (or write code to send this token to server app).
You can read more at the following questions, one of them you have read before with one of your previous questions:
How to implement a GCM Hello World for Android using Android Studio
Adding Google Cloud Messagin (GCM) for Android - Registration process
For more information:
Key Concepts from Google Cloud Messaging: Overview
Credentials
Sender ID A unique numerical value created when you configure your API project (given as "Project Number" in the Google Developers Console). The sender ID is used in the registration process to identify an app server that is permitted to send messages to the client app.
API Key An API key saved on the app server that gives the app server authorized access to Google services. In HTTP, the API key is
included in the header of POST requests that send messages. In XMPP,
the API key is used in the SASL PLAIN authentication request as a
password to authenticate the connection. You obtain the API key when
you configure your API project.
Registration Token An ID issued by the GCM connection servers to the client app that allows it to receive messages. Note that
registration tokens must be kept secret.
Hope this helps!
GCM now uses the concept of an InstanceID which represents a single install of an app on a device (Android or iOS). Each InstanceID can issue several tokens. These tokens are used to identify the InstanceID and can expire and be refreshed.
On the client device, you initialize an InstanceID, then with that InstanceID you generate a token (registration token). You send that token to your server, which uses the token to send messages to the InstanceID (installed application). If that token is invalidated for any reason like the application is uninstalled or the token is compromised, a new token should be generated and sent to your server.
I am still successfully registering with registration Id method until 11 May 2016
if (checkPlayServices()) {
gcm = GoogleCloudMessaging.getInstance(this);
regid = getRegistrationId(context);
if (regid.isEmpty()) {
registerInBackground();
}
} else {
Log.i(TAG, "No valid Google Play Services APK found.");
}
APA91bHLUfr71D6K7VTrRH3LGiLFxGNr3qRi3xOB_yNl0fLYsqhlgYXxHzOhQx2WKgqZI3sqxa1ZPORa0-5YBZ1_OFLm9cEg1bTh7wtrpCsHW91MSs2BMIXrHEqyjj2TeoVxnAzA5U8s
I have questions. How can I handle situation when GCM return canonical id.
I found few same questions on StackOverflow, but there is no solution. Amazon SNS Documentation about token management says that SNS handle this situation automatically. When GCM return canonical id amazon SNS update old tokens with new ones. But how can I know about that? I have my own database with all registered token and endpoints. I don't know if amazon was update token or not and send notification to all of them. As result lots of duplicate messages on device.
P.S. Server have to support multiple devices for one account.
Amazon SNS will handle token management only if your app is registered with them. Since you have your own database and endpoints, you would have to manage it yourself.
After pushing the message from the server, you would recieve the canonical id in the response.
As per Google's docs,
A canonical registration ID is the registration token of the last
registration requested by the client app .This is the ID that the
server should use when sending messages to the device.
If you try to send a message using an old registration token, GCM will
process the request as usual, but it will include the canonical ID in
the registration_id field of the response. Make sure to replace the
registration token stored in your server with this canonical ID, as
eventually the old registration token will stop working.
It is good practice to update your registration id with the canonical id returned after the push.
Also if your device is receiving duplicate notifications these could help:-
It could be due to a bug in the client app triggering multiple registrations for the same device. So make sure the same device is not getting registered many times.
Also, if you uninstall the app from device and you try to send a push to that device, you would get a NotRegistered error from GCM server. Then your server should delete the registration token and not use that registration token again to push messages.
P.S. Even if one user has multiple devices, your db mappings should be such that :- each device of the user will have a different registration token and each of the tokens will be mapped to a single user.
Since the tokens are different, receiving the same message pushed on all devices of the user would not be a problem.
Hope this helps! Cheers!
Please take a look at http://mobile.awsblog.com/post/Tx223MJB0XKV9RU/Mobile-token-management-with-Amazon-SNS for information on how to manage the mobile tokens.
When do orphaned GCM Registration IDs expire?
Steps to reproduce:
gcm.register(gcmSenderId) and receive a Registration ID
Verify receipt of push notifications
Factory Reset
gcm.register(gcmSenderId) and receive a Registration ID
Verify receipt of push notifications
Now, however, you can still send to the old Registration ID and receive "success:1". When, if ever, does that Registration ID expire and under what circumstances?
Registration ID generate using this Instance ID API
The client app obtains registration token using the Instance ID API.
for more description here
Registration ID expire and under the Instance ID lifecycle
your app or the Instance ID service may need to refresh tokens in the
event of a security issue or when a user uninstalls and reinstalls
your app during device restoration. Your app must implement a listener
to respond to token refresh requests from the Instance ID service.
here you can find a good explanation
EDIT
summarized:
there is no expiration time defined by GCM server
you tell the GCM server when the reg ID expires
if you do not tell the GCM Server about the expiration, it will not expire, even if the app was uninstalled on the respective device
google reserves the right to update the IDs, but there is no "rule", google may (but not necessarily does) update it at any time, but if so, you will be informed by receiving a canonical_id
During a registration request from a subscriber app to the GCM server, the app includes a senderID/projectID and its context. And my guess is when the GCM framework on the client receives the app request, it prepares a request by adding the app package name (uniquely identify the app), device ID (uniquely identify the device), the senderID.
Are there any additional parameters added by the GCM framework?
Is there a relationship between these parameters and the registration ID (or is the registration ID generated randomly)?
Maybe this can help. If you look at table 1 on the attached link, you'll find necessary credentials for GCM:
link
In my android application, I have utilized G+ logins to authenticate the user on the device, and I have implemented a basic GCM server to get a GCM registration ID for that device as well.
Once a device has both authenticated the user and received a GCM registration ID, I'd like it to let my server know that, for example, registration ID XYZ is associated with tim#gmail.com. This part I understand how to do. What I'm not sure of is how I can make sure that it's REALLY tim#gmail.com.
How can I be sure that the email/GCM registration ID pairs coming from devices is authentic?
Google allows you to verify back-end calls from your Android app by utilizing GoogleAuthUtil
to retrieve a string called an “ID Token”. You send the token to your back end and your back end can use it to quickly and cheaply verify which app sent it and who was using the app.
By passing the ID token with your registration ID call to the server, you can verify that the message is authentic and from your Android app.