14

In the official docs and this question, Google recommend re-registering GCM because the registration ID could change.

One hypothesized way it can happen is that during update, the all is uninstall and then installed. If a GCM notification is received during that gap, NotRegistered could be returned and the GCM registration ID could be invalidated.

If Google Play updates my app automatically, what's the most robust way to deal with that kind of scenario and re-register? In an app like WhatsApp, the user may never explicitly launch any activity unless a GCM notification is received. So the user is basically "lost" until he accidentally stumbles upon an activity.

In https://stackoverflow.com/a/14955308/111021 it is mentioned that the "Canonical ID" will be included so that the 3rd party server can update the registration ID. But in the doc it is not explicitly stated that this kind of scenario is covered (i.e. GCM may mistake the app as "uninstalled" during the update gap, in which case it seems to me a canonical ID will not be generated and I'll go straight to NotRegistered).

How does a "high availability" app like WhatsApp or other messager apps deal with this?

Community
  • 1
  • 1
kizzx2
  • 18,775
  • 14
  • 76
  • 83
  • Also similar: http://stackoverflow.com/questions/11422806/why-do-gcm-docs-recommend-invalidating-registration-on-app-update http://stackoverflow.com/questions/11590482/do-gcm-registration-ids-expire http://stackoverflow.com/questions/16838654/handling-registration-id-changes-in-google-cloud-messaging-on-android/16839326 – trante May 21 '14 at 07:05

3 Answers3

6

WhatsApp is not a good example. If you check the list of running services on your Android device, you'll see that WhatsApp keeps a service running at all times on your device. Therefore they don't rely on the app being registered to GCM (I'm not sure if they even use GCM).

The reason Google recommend to re-register after the app is upgraded is to overcome a bug that might cause the app to be unregistered during the upgrade.

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.

(Quote from here).

Since you can't re-register to GCM until your app is launched again, there is nothing more robust you can do, other than checking in your main activity if the app's version has changed, and then re-register to GCM if it has.

Community
  • 1
  • 1
Eran
  • 387,369
  • 54
  • 702
  • 768
  • That quote is just from another Stack Overflow, is that the official behavior? That post says "known cause" but doesn't cite any reference. – kizzx2 May 22 '14 at 09:20
  • @kizzx2 That quote is by Costin Manolache, a Google eployee from the team that developed GCM. Therefore it's as official as it can get. – Eran May 22 '14 at 10:04
  • @Loop That's not accurate. This question is about the case in which the device becomes unregistered. In this case the notification is not delivered, and the server gets NotRegistered error. The case you are refering to is the case in which the app registers again and gets a new registration ID, in which case both old and new registration ID will work. – Eran May 25 '14 at 20:02
6

What about below solution:

Create a BroadcastReceiver for intent ACTION_PACKAGE_REPLACED. You will receive this intent when a new version of the package gets installed. Once you get this intent you can re-register to GCM for new registration Id.

Broadcast Action: A new version of an application package has been installed, replacing an existing version that was previously installed. The data contains the name of the package.

Vineet Shukla
  • 23,865
  • 10
  • 55
  • 63
3

It would be interesting to know for what reason you want to use GCM in a highly available App. Especially the number of requests and if they are time sensitive.

In general from my own experience I can recommend, that GCM is far away from being highly available. Messages get lost or take a couple of minutes to arrive at the client. If you really want to guarantee 100% message delivery, you should use Sockets in a background service and reestablish the connection every time it gets lost. (Btw: that is the approach WhatsApp uses).

If you want to continue using GCM: maybe consider to reschedule your message on the server for a minute when the GCM server replies with NotRegistered.

Stefan Medack
  • 2,731
  • 26
  • 32