Handle GCM Canonical Id with Amazon SNS - android

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.

Related

registring on gcm multiple time from same device will generate multiple id or same and multiple users on same device

I want to know If I am registering my android app multiple time on gcm from same device will I get different registration id each time or the same one once registered?
Coming onto my second problem which is as below
if user1 logs out and user2 logs in the app on the same device. Now suppose a notification for user1 is sent from the server. Will the user2 get that notification or not if yes then how can it be avoided?
if user1 is logged in the app but user2 re-installs the app and logs in but server still thinks that user1 is logged in that device hence when we send the notification to user1 it will be delivered to user2. How can these be handled?
if my andriod app tries to register multiple time on gcm, will it get
different registration id or the same one?
AFAIK, this will be handled by GCM but as stated in this forum the solution would be to filter them on the client side. Your GCM notification should pass on which user it is for. Then in your onReceive method you should check who is currently logged in.
For your last question, according to the documentation - Registering:Client Apps
If a bug in the client app triggers multiple registrations for the same device, it can be hard to reconcile state and the client app might end up with duplicate messages.
Implementing canonical IDs can help you more easily recover from these situations. 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.

Should I generate android GCM registration ID app specific or user specific?

I am developing an app which has login functionality.I am generating only one gcm registration ID per app. If other user sign's in in same app he will start receiving notifications intended for the previous user.
How to handle this situation, so that each user will get notification intended for his/her?
Should I generate gcm reg id for each user?
What is the standard way to handle this situation?
You could try the following things:
When the user logs off, send a request to delete the token on your server, and erase it on your app;
Once the user logs off, you could simply remove the association of "User ID" to "GCM Token" (Or Registration ID) on your server. And when someone logs in again, you make a new association to that Token.
The GCM Token is app specific, but the association you make on your server is totally up to you.
And I can't stress it enough, the token generated by GCM is APP SPECIFIC. If your user logs in on multiple devices, your server should handle that, associating the user ID to multiple Registration ID Tokens.
An ID issued by the GCM servers to the Android application that allows
it to receive messages. Once the Android application has the
registration ID, it sends it to the 3rd-party application server,
which uses it to identify each device that has registered to receive
messages for a given Android application. In other words, a
registration ID is tied to a particular Android application running on
a particular device.
And from the docs, your server should also:
Before you can write client apps that use GCM, you must have an
application server that meets the following criteria:
Able to communicate with your client.
Able to send properly formatted requests to the GCM connection server.
Able to handle requests and resend them using exponential back-off.
Able to store the API key and client registration tokens.
Able to generate message IDs to uniquely identify each message it sends. Message IDs should be unique per sender ID.
EDIT: You can read more about GCM here.
For further reading, you could also read more on Device Group Messaging.
You can also download some code samples here.
You should store regID as per user.
This is because there is test cases that user1 logs out and user2 logs in. In that case if you have stored regID app specific and not binding with user then user2 will also get notification.
So you need to store regID as per user , app and as well as device specific.
Of course yes every time someone downloads your app, your app should register them with the GCM and be given a reg token, this needs to be sent to your app server, on your app server you need to sort out who you are sending the notification too. you should probably send some login info and reg token when they login so you can identify each person, then write some php or Jquery to send to individual users or all. you should also send the reg token every time they login as these can change without warning.
Your app server should be able to handle removing unused reg tokens and adding new ones
Each android device generate a Unique GCM reg id. push notification from server side will send according to the device id. So at Login time you can send GCM reg id to your server. So from server side push notification will send to device.., that is actual functionality.
Hope this will help

App receives duplicate notification using GCM after reinstalling [duplicate]

This question already has answers here:
Do old GCM tokens live on even after an uninstall?
(2 answers)
Closed 7 years ago.
I'm currently trying to use GCM to send notification to user and currently I'm still studying on how I can maximize it. For now I just use the sample project provided on the documentation here and I use the gcm-client sample to work on it.
Now using this project from Git I tried to push a message using the registration ID created by the app and yes it successfully delivers the message.
Now the problem is that after I uninstalled the application. After I reinstall it it will generate a new registration ID wherein I store it on a server together with the previous one except that I can't tag the previous registration ID to not receive any further message since the uninstall might happen when user has no internet connection. After that I send a message to two registration ID's which is the ID before uninstalling the app and the ID after reinstalling the application. What happen is that I receive two push messages eventhough I expected it to only get one since the app already changes the registration ID.
I expect that the app might receive twoor more duplicate apps if ever I also updated the app since as said on documentation the registration ID might change on update.
Any workaround I can do to handle this duplicate messages?
From the official documentation:
How uninstalled client app unregistration works
A client app can be automatically unregistered after it is
uninstalled. However, this process does not happen immediately. What
happens in this scenario is:
The end user uninstalls the client app.
The app server sends a message to GCM connection server.
The GCM connection server sends the message to the GCM client on the device.
The GCM client on the device receives the message and detects that the client app has been uninstalled; the detection details depend on the platform on which the client app is running.
The GCM client on the device informs the GCM connection
server that the client app was uninstalled.
The GCM connection server
marks the registration token for deletion.
The app server sends a
message to GCM.
The GCM returns a NotRegistered error message to the
app server.
The app server should delete the registration token.
Note
that it might take a while for the registration token to be completely
removed from GCM. Thus it is possible that messages sent during step 7
above get a valid message ID as a response, even though the message
will not be delivered to the client app. Eventually, the registration
token will be removed and the server will get a NotRegistered error,
without any further action being required from the app server.
However, it can apparently happen that you still get the notification for the old registration ID, as users state in other questions:
Android GCM and multiple tokens
Unregistering and re-registering for GCM messages causes two regId's to be valid. Is this as intended?
Do old GCM tokens live on even after an uninstall?
For this problem, there is a functionality called "canonical IDs":
Canonical IDs
If a bug in the client app triggers multiple registrations for the
same device, it can be hard to reconcile state and the client app
might end up with duplicate messages.
Implementing canonical IDs can help you more easily recover from these
situations. 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.
#KaHel When client app was uninstalled regId will be valid during some time, you are right. But, when client app will be installed again and your push server try to send message on old reg id that message will be successfully sent but GCM server put cannonical_id in response. And you should correct processes this response with cannonical_id. How do this i described at this post and there is not big documentation about cannonical_id. I.e. as soon as you get cannonical_id from GCM server you should immediately replace old reg_id by new one value. It will allow you not to produce a many regIds for one client, just one to one.
After reinstal you will get new RegId and prev not valid anymore. So, even if you send push to both RegIds, only last will received it.
You can implement logic for accounts in application.
For example, when user login in application you send his GoogleId + RegId. After reinstall of application and relogin you just update RegId on server. So, you can have only one RegId for every user.
There is problem: only one device will receive push msg (if you login in 2 devices with same account). So, you can send to server GoogleId + RegId + DeviceId after start application.

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

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

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

Categories

Resources