Suscribir temas con el token de Google Cloud Messenger, argumento inválido recibido

Estoy siguiendo el ejemplo que google proporciona para registrar el token gcm: https://developers.google.com/cloud-messaging/android/start

He generado correctamente el archivo google-services.json y puedo recibir los tokens push. Pero cuando estoy tratando de suscribirme a cualquier tema con el código de seguimiento:

// Register the user to the global topic. This will help the device to be register on GCM GcmPubSub pubSub = GcmPubSub.getInstance(this); pubSub.subscribe(token, "/topics/global", null); 

Se produce la excepción INVALID_ARGUMENT:

 01-05 14:05:24.435 D/RegIntentService( 4330): java.io.IOException: INVALID_PARAMETERS 01-05 14:05:24.435 D/RegIntentService( 4330): at com.google.android.gms.iid.zzc.zzb(Unknown Source) 01-05 14:05:24.435 D/RegIntentService( 4330): at com.google.android.gms.iid.zzc.zza(Unknown Source) 01-05 14:05:24.435 D/RegIntentService( 4330): at com.google.android.gms.iid.InstanceID.zzc(Unknown Source) 01-05 14:05:24.435 D/RegIntentService( 4330): at com.google.android.gms.iid.InstanceID.getToken(Unknown Source) 01-05 14:05:24.435 D/RegIntentService( 4330): at com.google.android.gms.gcm.GcmPubSub.subscribe(Unknown Source) 01-05 14:05:24.435 D/RegIntentService( 4330): at gcm.play.android.samples.com.gcmquickstart.RegistrationIntentService.subscribeTopics(RegistrationIntentService.java:105) 01-05 14:05:24.435 D/RegIntentService( 4330): at gcm.play.android.samples.com.gcmquickstart.RegistrationIntentService.onHandleIntent(RegistrationIntentService.java:65) 01-05 14:05:24.435 D/RegIntentService( 4330): at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65) 01-05 14:05:24.435 D/RegIntentService( 4330): at android.os.Handler.dispatchMessage(Handler.java:99) 01-05 14:05:24.435 D/RegIntentService( 4330): at android.os.Looper.loop(Looper.java:137) 01-05 14:05:24.435 D/RegIntentService( 4330): at android.os.HandlerThread.run(HandlerThread.java:60) 

Este es un ejemplo de tokens push que recibo:

 e3r6xnFGK3E:APA91bG9oY0A7QCf86BXXh8ADzycct5QJUONTXMH3pApCkcwty0A6UXo6zLLx3Hl3ubMgBY65ldxuZzSF20nahZAq-4SiUMRS0YYStJtldK85lzrO-xM5KvM_Jigpaka-RN5TLb8D1Op 

He comprobado la documentación sobre suscribir un tema, pero no hay nada que dice por qué estoy recibiendo INVALID_PARAMETER excepción:

Https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmPubSub.html#subscribe(java.lang.String, java.lang.String, android.os.Bundle)

Cualquier ayuda es apreciada.

Pd Existe el código fuente completo para registrar los tokens:

 import android.annotation.SuppressLint; import android.app.IntentService; import android.content.Intent; import android.os.Bundle; import android.os.ResultReceiver; import android.util.Log; import com.google.android.gms.gcm.GcmPubSub; import com.google.android.gms.gcm.GoogleCloudMessaging; import com.google.android.gms.iid.InstanceID; /** * Intent service used to retrieve and save the registration token needed * Extracted from here * https://github.com/googlesamples/google-services/blob/master/android/gcm/app/src/main/java/gcm/play/android/samples/com/gcmquickstart/RegistrationIntentService.java */ public class RegistrationIntentService extends IntentService { public static final String TAG = "RegistrationIntentService"; public static final String INTENT_KEY_UPDATE_SERVER_TOKEN_CALLBACK = "services.RegistrationIntentService.INTENT_KEY_UPDATE_SERVER_TOKEN_CALLBACK"; private ResultReceiver mResultReceiver; public static final String BUNDLE_KEY_GCM_TOKEN = "services.RegistrationIntentService.BUNDLE_KEY_GCM_TOKEN"; public RegistrationIntentService() { super(TAG); } @SuppressLint("LongLogTag") @Override protected void onHandleIntent(Intent intent) { // Get the result receiver Bundle extras = intent.getExtras(); if (extras != null && extras.containsKey(INTENT_KEY_UPDATE_SERVER_TOKEN_CALLBACK)) { mResultReceiver = (ResultReceiver)extras.get(INTENT_KEY_UPDATE_SERVER_TOKEN_CALLBACK); } try { InstanceID instanceId = InstanceID.getInstance(this); String token = instanceId.getToken(getString(R.string.gcm_defaultSenderId), GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); Log.i(TAG, "GCM Registration Token: " + token); // TODO: Send registration token to the server if (mResultReceiver != null) { Bundle bundle = new Bundle(); bundle.putString(BUNDLE_KEY_GCM_TOKEN, token); mResultReceiver.send(0, bundle); } // Register the user to the global topic. This will help the device to be register on GCM GcmPubSub pubSub = GcmPubSub.getInstance(this); pubSub.subscribe(token, "/topics/global", null); Logger.v(TAG, "User correctly register to the global token"); } catch (Exception e) { Log.d(TAG, "Faield to complete token refresh", e); } } } 

Y este es el contenido de google-services.json

 { "project_info": { "project_id": "NOT_SHOWN-aa10f", "project_number": "11046079110", "name": "NOT_SHOWN" }, "client": [ { "client_info": { "mobilesdk_app_id": "1:11046079110:android:b918cc51ed907631", "client_id": "android:NOT_SHOWN", "client_type": 1, "android_client_info": { "package_name": "NOT_SHOWN" } }, "oauth_client": [], "api_key": [], "services": { "analytics_service": { "status": 1 }, "cloud_messaging_service": { "status": 2, "apns_config": [] }, "appinvite_service": { "status": 1, "other_platform_oauth_client": [] }, "google_signin_service": { "status": 1 }, "ads_service": { "status": 1 } } } ], "client_info": [], "ARTIFACT_VERSION": "1" } 

Parece que ninguno ha resolver este problema hasta ahora, así que voy a dar la solución que encontré.

El problema es que tenemos varios procesos que registran el GCM. Así que lo que sucede en el 60% de los casos es que después de registrar nuestro propio dispositivo, en la misma aplicación, el otro proceso de registro en GCM con su propio remitente. Por lo tanto, cuando estábamos tratando de suscribirse a un tema, el token gcm no es válido porque el mismo dispositivo, la misma aplicación ha registrado el gcm para otro remitente.

Para solucionar el problema, lo que hemos hecho es obtener el identificador del remitente del otro proceso y adjuntarlo a nuestro remitente.

Digamos que nuestro identificador de remitente es "1234567", y su identificador de remitente es "7654321", por lo que cuando registramos nuestra aplicación en GCM, en lugar de analizar sólo "1234567", usamos "1234567,7654321", separados por coma.

Esto nos permite obtener un token GCM que sea válido tanto para nosotros como para el otro proceso, mientras que si el otro proceso registra el GCM después de nosotros, no invalidará su propio token GCM. (Su token GCM seguirá siendo válido porque incluimos su remitente como parte de la solicitud).

Saludos desde Dubai!

  • GCM 3.0 - gcm no muestra automáticamente la notificación con el parámetro de notificación
  • ¿Es posible usar GCM para enviar notificaciones push entre diferentes aplicaciones?
  • Enviando mensaje a la aplicación del servidor con GCM
  • GCM duplicó mensajes
  • Notificación de emisión de GCM Cordova no funciona cuando no se ejecuta la aplicación
  • Anular el registro de un dispositivo de GCM mediante la identificación de registro en Android
  • No se puede resolver com.google.android.gcm.GCMBaseIntentService; Estudio de Android
  • GCM: enviar notificaciones sólo para el usuario actual que ha iniciado la aplicación
  • Android GCM Java Server - notificación de emisión sin datos de mensajes
  • ¿Son confiables las notificaciones push de Android?
  • Script de GoogleCloudMessaging PHP siempre devolviendo invalidregistration
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.