I wonder what is the lifecycle of registrationId(device_token)
e.g eD3Fa1yVqx8:APA91bH5gNrC-jhUqaoRwyFLfD2ik4NXwCXohwhm_9CM5hnY9wFwUAOiO_O12Or-dm60sUqy9gN2ZW6mw5i90RyNhb-zHilvtcJczPjZoQlm_4lKNKDejC_1_xiqmYoZnSxaFfVqSA1d
How to handle the situation if it's changed?
As far as the information on the official docs goes, there is no information about the token being changed by Google. However you should change it periodically.
Quoting https://developers.google.com/cloud-messaging/registration#automatic-retry-using-exponential-back-off
Keeping the Registration State in Sync
To protect the client app and app server from potential malicious
re-use of registration tokens, you should periodically initiate token
refresh from the server. When GCM registration token refresh is
initiated from server side, the client app must handle a
tokenRefreshed message with the GCM registration client/server
handshake.
I faced some situations where Registration ID changed. But, i don't know how and when.
So, to handle these situations i updated my app to send Registration ID every time the app is launched. I sent Registration ID with device id and check my database if the registration id changed i updated it.
Related
I am following a GCM-Android integration example from the official guide.
In particular I am confused about the following lines in the above linked class:
// You should store a boolean that indicates whether the generated token has been
// sent to your server. If the boolean is false, send the token to your server,
// otherwise your server should have already received the token.
Now I call the intent service each time my main activity launches and I believe that instanceID is responsible for initiating the token refresh.
Should I check the Shared Prefs value each time I initiate this GCM registration intent from my Main Activity. However refresh will fail in this case because after initial token fetch the condition will always be true.
Should I discard the shared prefs logic - this way a fresh token will be sent to my server each time. What is the proper way of doing this? How does the token refresh worrk and when does it refresh?
Yes, you don't need to save it in sharedPreference. To protect the client app and app server from potential malicious re-use of registration tokens, you should periodically initiate token refresh from the server. When GCM registration token refresh is initiated from server side, the client app must handle a tokenRefreshed message with the GCM registration client/server handshake.
Based on the document, backing up the registration token that Google Cloud Messaging registration returned can cause unexpected behavior in notifications for the restored app. This is because when a user installs your app on a new device, the app must query the GCM API for a new registration token. If the old registration is present, because the system had backed it up and restored it, the app doesn't seek the new token. To prevent this issue from arising, exclude the registration token from the set of backed-up files.
Here's a demo app for Google Services - MyInstanceIDListenerService: https://github.com/googlesamples/google-services/blob/master/android/gcm/app/src/main/java/gcm/play/android/samples/com/gcmquickstart/MyInstanceIDListenerService.java#L38
For more information, please read the Official Google Documentation here: https://developers.google.com/cloud-messaging/registration
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
I am just started to learn the GCM in android. I did not find this in the documentation that Does Google keep the GCM Registration ID always?.
Can a developer remove it, any way to access this database programmatically?
Besides the periodic refresh(which is rare),
An existing registration ID may cease to be valid in a number of
scenarios, including: If the application manually unregisters by
issuing a com.google.android.c2dm.intent.UNREGISTER intent. If the
application is automatically unregistered, which can happen (but is
not guaranteed) if the user uninstalls the application. If the
registration ID expires. Google might decide to refresh registration
IDs. For all these cases, you should remove this registration ID from
the 3rd-party server and stop using it to send messages. Happens when
error code is NotRegistered.
About the periodic refresh:
Note that Google may periodically refresh the registration ID, so you
should design your Android application with the understanding that the
com.google.android.c2dm.intent.REGISTRATION intent may be called
multiple times
Read more:
http://developer.android.com/google/gcm/gcm.html
http://developer.android.com/google/gcm/adv.html#reg-state
Do GCM registration id's expire?
I'm developing an application that uses C2DM to receive push notifications. I've implemented the whole C2DM circuit (both client and server) and it's working fine.
Currently my applicacion has a button to bootstrap the C2DM registration, when receiving the registration id token from Google I call a webservice in my app server to associate the device with the registration id.
I'm going to implement authentication in my application and I have a few question related to the handling of the C2DM registration.
The client application (ie the Android one) will have a login screen as the first screen so the user can enter the credentials. As soon as the credentials get validated I'm planning on calling the C2DM registration so the user gets associated with a registration id token. Is this ok? In later executions of the application I will probably store the credentials or some sort of token so the user doesn't need to enter the credentials again, Should I also fire the C2DM registration when the application launches?
I'm aware that Google may eventually update the registration id. Is it a good practice to also update the registration id on a regular basis? If so, when should be appropiate? Does the registration id token expire?
What happens in the rare case of a desynchronization of the registration id between the client and the server (eg a new registration id arrives at the client, in the middle of that a new event is fired on the server with the old registration id, then the registration id arrives at the server)? Will Google handle this cases? Should my app server handle this cases?
What happens if the server is not reachable when a new registration id arrives from Google? Should I backoff and schedule an Alarm to try again?
Can you think of any other pitfalls with this?
1) I would fire the C2DM registration as soon as possible. Nothing in particular, but since the request is asynchronous, firing it up early will help me get the reg ID sooner. However, no need to fire the registration each time the app starts. Once is sufficient.
2) Whenever Google decides to update the reg ID it will send it to the device and you need to do the same steps you followed when you receive the reg id for the first time i.e. convey it to the server.
3 & 4) You may want to go through this documentation. It stresses the fact that you need to make it sure that you send the registration ID to your server and keep on trying. I assume here that if the reg ID is refreshed, and your server still has the old ID, it will not be able to send messages to the device. It will receive a 200OK with an Error Code of InvalidRegistration which means a (missing or) bad registration id.
5) Cannot comment much - would say that it depends on the design of your application. But one thing worth noting is that C2DM is still in Beta so expect things to be different in the long run.
Try to prompt the user with a choice of google accounts that are already on the phone. The http://code.google.com/p/chrometophone/source/checkout shows this. Look at SetupActivity.java for getGoogleAccounts(), etc.