I developed an application which used GCM technology and everything is OK.
I observed that the registration ID of the device changes after a period of time and this has caused a problem in my app because my app is dependent on the Reg ID.
So how I can get a fixed Reg ID for clients?
I read the 2 reasons over here when you GCM Registration Id might change:
You’ll need to re-register every device each time you update your
app.
You’ll also need to re-register a device if the version of Android it’s running has been updated
P.S: The below old answer's reference has been removed from Google's page, so might not be valid anymore
If you see the second point under the heading Enable GCM on Architectural Overview page, it says:
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.
So, for handling that you should have a Broadcast Listener which could handle com.google.android.c2dm.intent.REGISTRATION intent, which Google send to the app when it has to refresh the registration ID. The broadcast receiver will have the onReceive method with an Intent. From the intent you can get the Bundle using which you can extract the new registration ID from Google. You can save that and send it to the 3rd part server to replace your previous registered ID for that user.
Also you may see this answer on the question In GoogleCloudMessaging API, how to handle the renewal or expiration of registration ID?.
Discussion on Should applications call gcm.register() every seven days to ensure valid registration IDs? question might also be of some use.
Hope this helps you understand how to handle it.
The 'periodical' refresh never happened, and the registration refresh is not included in the new GCM library.
The only known cause for registration ID change is the old bug of apps getting unregistered automatically if they receive a message while getting upgraded. Until this bug is fixed apps still need to call register() after upgrade, and so far the registration ID may change in this case. Calling unregister() explicitly usually changes the registration ID too.
The suggestion/workaround is to generate your own random identifier, saved as a shared preference for example. On each app upgrade you can upload the identifier and the potentially new registration ID. This may also help tracking and debugging the upgrade and registration changes on server side.
Related
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.
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 building GCM into my app and I want to make sure I don't end up with duplicate device ID's.
Is there a 'best practice' for dealing with device ID's? My original though was when the app loads it calls gcm.register, and posts the ID to my server, and if the key isnt in my database, I'll store it, then when I send out a notification, loop through the DB and send the messages.
But I as wondering if the ID ever changes, I don't want to send multiple messages to one device.
yes it is possible for the ID to change. If you take a look at the tutorial in the SDK, every time the app is updated to a new version it will go and get a new ID because the previous ID is not guaranteed to work.
specifically take a look at this page
http://developer.android.com/google/gcm/client.html
Check if app was updated; if so, it must clear the registration ID
since the existing regID is not guaranteed to work with the new
app version.
I read the 2 reasons over here when you GCM Registration Id might change:
You’ll need to re-register every device each time you update your
app.
You’ll also need to re-register a device if the version of Android it’s running has been updated
P.S: The below old answer's reference has been removed from Google's page.
In addition to #tyczj's answer of change of ID's on updating the app, Google says that it may also automatically refresh the ID's. If you read the second point under the heading Enable GCM on Architectural Overview page, it says:
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.
Just an addition info that for handling this case you should have a Broadcast Listener which could handle com.google.android.c2dm.intent.REGISTRATION intent, which Google send to the app when it has to refresh the registration ID. The broadcast receiver will have the onReceive method with an Intent. From the intent you can get the Bundle using which you can extract the new registration ID from Google. You can save that and send it to the 3rd part server to replace your previous registered ID for that user.
I think it would be better if you can have login based app and id validated or update at each login. I have a similiar app and its is working for me.
Does the registration id for a device - app combo ever change? There is no mention of it's consistence in the docs (that I could find).
Also, will the same registration id be assigned to a device after an un-install and reinstall of the app?
Yes it can change. From the doc
Although the com.google.android.c2dm.intent.REGISTRATION intent is typically received after a request was made by the application, Google may periodically refresh the registration ID. So the application must be prepared to handle it at any time.
No, it won't be the same.
I know that C2DM registrations expire, and you are supposed to periodically refresh the registration ID. Is this the case with GCM? by looking at the following code on the Android GCM guide (shown below), it seems like you only do it once and don't need to refresh, but I dont see that explicitly written anywhere, so I just wanted to check.
final String regId = GCMRegistrar.getRegistrationId(this);
if (regId.equals("")) {
GCMRegistrar.register(this, SENDER_ID);
} else {
Log.v(TAG, "Already registered");
}
EDIT: THIS ANSWER IS WAY OUT OF DATE, I HAVE NO IDEA WHAT THE CURRENT BEHAVIOR IS
I found the answer myself. You don't explicitly need to re-register all the time, just once according to the example in the docs.
Also, unlike previous versions of GCM and C2DM, Google itself does not refresh the registration itself now: once you have the registration id from the initial registration you are good to go, except for one case: you do still need to re-register when the user upgrades to a new version (this case is also handled in the example in the link above):
When an application is updated, it should invalidate its existing
registration ID, as it is not guaranteed to work with the new version.
Because there is no lifecycle method called when the application is
updated, the best way to achieve this validation is by storing the
current application version when a registration ID is stored.
I think that it is refreshed eventually, yes. From the official docs:
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.
This could happen in a request to GCM from your 3rd-party server, which returns a json response with the error Unregistered Device.
Once this happen, it'll be up to you to refresh the corresponding id's.
http://developer.android.com/guide/google/gcm/gcm.html