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.
Related
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.
I'm a bit confused about how to manage registration ids for all app installations.
In the app server database I have a User table and a UserDevice table. Every User may have many UserDevices. Each UserDevice have a registration id. So when a user should be notified I send the message to all the registration id's for all the devices of the user.
But when the application is reinstalled, Android is updated or something else happens that causes the registration id to change, the app will send a new registration id to our app server. But I have no way to know if this is a new device or if an existing UserDevice should be updated with the new registration id.
How is this supposed to be handled? My first thought is to send a persistent hardware ID as well as the registration ID, but perhaps there is a better way?
You don't have to worry about this. If the user does reinstall the app and the token is refreshed just add it to the users list of tokens (keeping the old one for now).
next time you send a notification to this user it will fail on the token that is no longer used. Now all you have to do when you get the fail reply from google is remove that token from your devices table.
Remember if you fail to send to a token for reasons such as invalidRegID or NotRegistered then the GCM will/has unregistered that token so it is no good so it needs to be removed from your list otherwise you will get in googles bad books for repeatedly sending to the same failed token. So remove ones that fail.
when my apps start i always check to see if the device is registered if it is I send the same token to my app server just incase it somehow got deleted.
Hope this helps
You could take a look at GCM's Device Group feature, which is explicitly intended for the "one user, many devices" problem:
https://developers.google.com/cloud-messaging/notifications
I use PushSharp and there I can use the different event handlers that are defined to handle subscription changes or expirations. The source code is available on github https://github.com/Redth/PushSharp/blob/master/PushSharp.Android/Gcm/GcmPushChannel.cs
You can probably apply the same logic to your application.
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
I just started to use Google Cloud Messaging and read about User Notifications.
According to this link, all the devices owned by a particular user will be notified at once.
In my case, a particular user is identified by his/her user_id and the database would look like this:
[user_id] [gcm_registration_id]
As per the demo, on the application side this registration_id is stored as persistent data.
What happens if the user uninstalls the app and the persistent data is gone?
Will I get the same Registration ID for the same App on the same device once the user re-installs the app?
Will Google invalidate these Registration IDs after some time?
will I get the same registration_id for the same app on the same
device once the user reinstalls the app?
YES. Reg id chnages in two cases. Either your app will register OR Google refreshes the Registration ID. SO until any one cases executes your are fine with old reg id.
By any chance google invalidates these registration_ids after some
time?
YES. Google refreshes the registration ID. GCM gives you the idea about handleing of updated registartion ID.
Handle updated id on client side
If the registration is successful, the GCM server broadcasts a com.google.android.c2dm.intent.REGISTRATION intent which gives the Android application a registration ID.
The Android application should store this ID for later use (for instance, to check on onCreate() if it is already registered). 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. Your Android application needs to be able to respond accordingly.
Actually the answer you accepted is not entirely correct.
I tested the case of un-installing and re-installing an app on a device, and in some cases you could get a different registration ID.
There are two cases :
You install an app, register to GCM and get a registration ID.
You un-install app
Your server sends a few messages to that registration ID, until you get a NotRegistered error from GCM (I believe you'll get that error only from the 2nd message you send).
You re-install the app
You receive a new registration ID when app register to GCM
If you now send a message with the old registration ID, it will still work, but you'll get the new registration ID in the response as canonical registration ID.
You install an app, register to GCM and get a registration ID.
You un-install app
The server doesn't send anything to that registration ID while the app is un-installed.
You re-install the app
You receive the same registration ID when app registers to GCM
I am trying to write an application which notifies a cellphone using GCM. I was able to implement basic functionality, but there is one question I'm still unsure of
As I understand, the flow goes like this:
Device start up
Device registers, obtains registration id
Server gets the knowledge of registration id on device
Server is using it's API key + registration id to send payload to device
Device receives payload.
One thing which is unclear to me is: what is a proper methodology to implement step #3?
I could not find any way to obtain a list of registered devices. Lets imagine, I am using GCM for a purpose of posting to a known device, and I could email that ID to myself and then register it on the server manually. But as I understand, it expires.
So, it there an expectation that I have to keep re-registering and somehow notifying server every time it happens?
Yes, your app on device must send registration ID to your server application in order for server to be able to send GCM messages. See third point in Enabling GCM.