I am following the example that google provides to register the gcm token: https://developers.google.com/cloud-messaging/android/start
I have generated correctly the google-services.json file and I am able to receive the push tokens. But when I am trying to subscribe to any topic with the follow code:
// 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);
It throws the INVALID_ARGUMENT exception:
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)
This is an example of push tokens that I receives:
e3r6xnFGK3E:APA91bG9oY0A7QCf86BXXh8ADzycct5QJUONTXMH3pApCkcwty0A6UXo6zLLx3Hl3ubMgBY65ldxuZzSF20nahZAq-4SiUMRS0YYStJtldK85lzrO-xM5KvM_Jigpaka-RN5TLb8D1Op
I have checked the documentation about subscribe a topic but there is nothing that says why I am receiving INVALID_PARAMETER exception:
https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmPubSub.html#subscribe(java.lang.String, java.lang.String, android.os.Bundle)
Any help is appreciated.
P.d. There is the complete source code to register the 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);
}
}
}
And this is the content of the 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"
}
If a subscriber can't acknowledge a message, Pub/Sub can forward the message to a dead-letter topic. For more information, see Forwarding to dead-letter topics. If you set a dead-letter topic, you can't enable message ordering. If you set a dead-letter topic, you can also specify the maximum number of delivery attempts.
You can publish messages with the gcloud command-line tool or the Pub/Sub API. The client libraries can asynchronously publish messages. In the Cloud Console, go to the Pub/Sub topics page. Click the topic ID. In the Topic details page, click Publish messages. In the Message body field, enter the message data.
Google Cloud Messaging, deprecated April 10 2018, has been deactivated and removed from Google's APIs. For equivalent functionality, use Firebase Cloud Messaging (FCM), which inherits the reliable and scalable GCM infrastructure, plus many new features.
The client libraries can asynchronously publish messages. In the Cloud Console, go to the Pub/Sub topics page. Click the topic ID. In the Topic details page under Messages, click Publish message.
It seems that none has solve this problem so far, so I am going to give the solution that I found.
The problem was we have several process which register the GCM. So what happens in 60% of the cases is that after we register our own device, in the same app, the another process register on GCM with its own sender. Thus when we were trying to subscribe to a topic, the gcm token is not valid because the same device, the same app has register the gcm for another sender.
To solve the problem, what we have done is get the sender id from the another process, then attach it to our sender.
Let's say our sender id is "1234567", and his sender id is "7654321", so when we register our app on GCM, instead of parsing only "1234567", we use "1234567,7654321", separated by coma.
This allow us to obtain a GCM token that is valid both for us and for the another process, while if the another process register the GCM after us, it won't invalidate own GCM token. (His GCM token will still be valid because we include its sender as part of the request).
Cheers from Dubai!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With