Android - How to implement Canonical IDs for GCM to prevent duplicates - android

I have implemented GCM in my app and my device gets two alerts after reinstalling the app.I have read about canonical id's but it's really hard to find information on how to use it or how/where to implement it. Google's docs are very vague sometimes and don't provide examples. This is how I do a normal registration to get the regID.
GCMRegistrar.register(this, getString(R.string.gcm_project_id));
Do I change this code to send a canonical registration and if so how? My server is not telling me there are any canonical ids it always says success 3(should be 2 for other device) and canonical 0. So there is no way for me to update the DB as it doesn't let me know there is a dupe.

You are mixing stuff, this call accepts the sender id taken from the google api console. The registration id is sent to you though the onRegistered method inside the GCMBaseIntentService which you should send to the server so you can use it in the push notifications sending. Now if you have an old registration id then google will send to your server the updated registration id AKA Canonical id in the response of the sending service.

Everything is we need to update existing registration id with canonical id in server where we have stored. You ca use this answer Update Canonical Id

Related

Handle GCM Canonical Id with Amazon SNS

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.

Updating GCM registration ID after device update

In order to get an updated registration ID once a user upgrades their android version, do I need to first unregister the original registration ID by calling unRegister before I get the new registration ID?
You don't have to un-register before registering again to GCM, unless you are changing the sender ID (project number) used to register. In fact, the registration ID may even stay the same if you register with the same sender ID.
You don't have to do that and if you do the registration ID will remain the same.
If you want to have a completely new and different registration-id you need to register with another project-id.
Also, if you change your package name for your project, the registration-id would change too.
Updating registration ID is not required if Android device get updated with newer Android version e.g. JellyBean to KitKat.
You have to update registration ID if your application is updated. In that case you don't have to un-register at all, just register again and clear stored previous ID in the local storage.
Android Developer page has well written chapter about GCM Advanced Topics. You should be interested in Unregistration and Keeping the Registration State in Sync
#Eran is absolutely right.Upgrading your android version won't change gcm registration id.However sometimes may be because of some bug in your app or uninstalling(and again reinstalling the app) gcm may change your registration id.But thankfully gcm provides the concept of canonical ids.So i don't think you will need to unregister your device from gcm for this case but you need to deal with the canonical id properly if it occurs.
Please refer here and have a read about canonical ids
Canonical IDs
On the server side, as long as the application is behaving well, everything should work normally. However, if a bug in the application triggers multiple registrations for the same device, it can be hard to reconcile state and you might end up with duplicate messages.
GCM provides a facility called "canonical registration IDs" to easily recover from these situations. A canonical registration ID is defined to be the ID of the last registration requested by your application. This is the ID that the server should use when sending messages to the device.
If later on you try to send a message using a different registration ID, GCM will process the request as usual, but it will include the canonical registration ID in the registration_id field of the response. Make sure to replace the registration ID stored in your server with this canonical ID, as eventually the ID you're using will stop working.

Persistance of gcm registration id

I am doing an android application which uses gcm.I came to know that when the application is uninstalled and re installed there is no guarantee to receive the same registration id again.So what I did is while logging in I take one unique Id from application server and whenever new registration id is made I am able to replace that in application server.So what my question is, I am not using the canonical id for replacing the latest registration id in gcm server.Will it cause any problem? Please help me.
Your solution is basically good, though I'm not sure whether that unique Id your server generates is associated with the device or the logged in user. If it's the former, make sure you persist it on the device's external storage, so that it doesn't get lost when the app is uninstalled. If it's the latter, I'm not sure how you are handling the case of the same user logging in on multiple devices.
While your strategy is good for maintaining the current registration ID on both the device and your server, you should still handle canonical registration ID responses from Google just to be safe.
On the server side, as long as the application is behaving well,
everything should work normally. However, if a bug in the application
triggers multiple registrations for the same device, it can be hard to
reconcile state and you might end up with duplicate messages.
GCM provides a facility called "canonical registration IDs" to easily
recover from these situations. A canonical registration ID is defined
to be the ID of the last registration requested by your application.
This is the ID that the server should use when sending messages to the
device.
If later on you try to send a message using a different registration
ID, GCM will process the request as usual, but it will include the
canonical registration ID in the registration_id field of the
response. Make sure to replace the registration ID stored in your
server with this canonical ID, as eventually the ID you're using will
stop working.
Source : http://developer.android.com/google/gcm/adv.html#canonical

gcm canonical id should be updated or not

I am working on an android project which uses gcm. I came to know that if we uninstall the appfrom device and reinstalled most of the time the device gets new registration id.Then if we do not delete the old one from application server and update, The messages will be sending to both ids and in the response it will be showing canonical id is present.My question is, at this point message will be successfully send to that device or not?
When you receive a canonical registration ID in the response from Google, the message was accepted by the GCM server and the GCM server would attempt to deliver it to the device. Whether it is actually sent to the device depends on whether the device is available (i.e. connected to the internet).
So if your server sends a GCM message to both the old ID and the new ID, the device will probably get two messages.
Canonical IDs
On the server side, as long as the application is behaving well,
everything should work normally. However, if a bug in the application
triggers multiple registrations for the same device, it can be hard to
reconcile state and you might end up with duplicate messages.
GCM provides a facility called "canonical registration IDs" to easily
recover from these situations. A canonical registration ID is defined
to be the ID of the last registration requested by your application.
This is the ID that the server should use when sending messages to the
device.
If later on you try to send a message using a different registration
ID, GCM will process the request as usual, but it will include the
canonical registration ID in the registration_id field of the
response. Make sure to replace the registration ID stored in your
server with this canonical ID, as eventually the ID you're using will
stop working.
(Source)
You can overcome this problem by assigning a unique identifier to each instance of your application. If you store that identifier in the device's external storage, it won't be deleted when the app is uninstalled. Then you can recover it when the app is installed again. If you send this identifier to your server along with the registration ID, you can check if your server has an old registration ID for this identifier, and delete it.
#Eran We have two option either to remove older registration ids or update with Key and position of canonical id. I prefer to update... You can view working code of mine i have answered here Steps to Update Canonical Ids

Google cloud messaging registering and unregistering

I am developing an app using the new Google Cloud Messaging Framework. We know that once we register our app we get a registration id. But what happens when the user unistalls the app through the device for a number of times and re installs again and again (there is no new notification sent till now). Now with many installations done google might return several new registration ids and now all the ids are saved in the app database.
If there is a notification to be sent it would be sent to all the ids previously saved also. Now my problem is that i think google is sending the notification to all the previous ids(so i get multiple notifications on the same device).
I hope i made my question clear and is there a solution to this.
You can assign a unique identifier to the app on each device. If you store that identifier on the external storage of this device, it won't be removed when the app is uninstalled. Then, when the app is installed again, you can send the registration ID along with that stored unique identifier. Your server will use the identifier to locate the old registration ID and replace it with the new one.
In addition, you should check for canonical registration IDs in the response you get from GCM. Each time to get a canonical ID, you should make sure you have that ID in your DB and remove the old ID (the one you used to send the message that got the canonical registration ID in its response).
I suggest you read the section Canonical IDs of the official documentation, as canonical IDs are specifically designed to solve your problem.
Every time you will send a message to an old registration ID Google will let you know what is the current canonical ID of the device you are sending a message to. Just make sure to replace your ID by this one.
Also make sure to check the code of the official demo here.

Categories

Resources