Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCM 3.0 Refresh registration token needed?

With the latest GCM update (3.0) is it still necessary to handle refreshing the registration token during situations such as reboot? This article discusses making GCM reliable and covers several conditions where the registration token can change. Are these steps necessary under the latest version? During the IO 2015 talk they talked as if the registration token was good until the app is uninstalled from the device.

InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
    GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
like image 493
Patrick Avatar asked Jun 03 '15 14:06

Patrick


2 Answers

The registration token shouldn't refresh after reboots, but there are other situations when it might get refreshed, so you need to handle it.

With the updated API you need to implement an InstanceIDListenerService in order to handle token refreshes as exemplified in the google-services#android#gcm sample app

    /**
     * Called if InstanceID token is updated. This may occur if the security of
     * the previous token had been compromised. This call is initiated by the
     * InstanceID provider.
     */
    // [START refresh_token]
    @Override
    public void onTokenRefresh() {
        // Fetch updated Instance ID token and notify our app's server of any changes (if applicable).
        Intent intent = new Intent(this, RegistrationIntentService.class);
        startService(intent);
    }

Regarding the other situations when the token refresh might happen.

  • Check https://developers.google.com/cloud-messaging/server-ref#error-codes , Unregistered Device error description:

An existing registration token may cease to be valid in a number of scenarios, including:
- If the client app unregisters with GCM.
- If the client app is automatically unregistered, which can happen if the user uninstalls the application. For example, on iOS, if the APNS Feedback Service reported the APNS token as invalid.
- If the registration token expires (for example, Google might decide to refresh registration tokens, or the APNS token has expired for iOS devices).
- If the client app is updated but the new version is not configured to receive messages.

For all these cases, remove this registration token from the app server and stop using it to send messages.

  • As per https://stackoverflow.com/a/16839326/313113 (as of EDIT 04.24.2014) it seems there is a bug when the user upgrades the app and you send a notification at the same time when the upgrade happens, the token gets unregistered, so you have to register again after an app upgrade. (not sure if it's still the case)
  • Token refreshes after backup/restore operation
  • The documentation at Keeping the Registration State in Sync even recommends doing token refreshes periodically from the server, for security reasons:

To protect the client app and app server from potential malicious re-use of registration tokens, you should periodically initiate token refresh from the server. When GCM registration token refresh is initiated from server side, the client app must handle a tokenRefreshed message with the GCM registration client/server handshake
See the API reference for more information on identity and token refresh procedure.

like image 165
Alex Bitek Avatar answered Oct 20 '22 03:10

Alex Bitek


EDIT: Check out the InstanceID docs as this shows how to handle token refreshing. https://developers.google.com/instance-id/ and https://developers.google.com/instance-id/guides/android-implementation

Its not very clear from a server PoV imho.

From https://developers.google.com/cloud-messaging/registration#keeping-the-registration-state-in-sync we have

To protect the client app and app server from potential malicious re-use of registration tokens, you should periodically initiate token refresh from the server. When GCM registration token refresh is initiated from server side, the client app must handle a tokenRefreshed message with the GCM registration client/server handshake. See the API reference for more information on identity and token refresh procedure.

Hmm, no link there for API reference - so looking at the server api here https://developers.google.com/cloud-messaging/server-ref#interpret-downstream we have a canonical_ids field which is

Number of results that contain a canonical registration token. See the registration overview for more discussion of this topic.

and a results field which has

Optional string specifying the canonical registration token for the client app that the message was processed and sent to. Sender should use this value as the registration token for future requests. Otherwise, the messages might be rejected.

For client side we have the new https://developers.google.com/android/reference/com/google/android/gms/iid/InstanceIDListenerService.html#onTokenRefresh()

Called when the system determines that the tokens need to be refreshed. The application should call getToken() and send the tokens to all application servers. This will not be called very frequently, it is needed for key rotation and to handle special cases. The system will throttle the refresh event across all devices to avoid overloading application servers with token updates.

So how you initiate token refresh from the server is beyond me! But in answer to your question - yes you do still need to handle token refresh client side!

EDIT: interesting read Handling registration ID changes in Google Cloud Messaging on Android

like image 2
Dori Avatar answered Oct 20 '22 05:10

Dori