MePo
MePo

Reputation: 1074

Custom Google cloud Messaging token

I would like to create a Google Cloud Messaging app but the problem is I would like to create Registration Token per user not per application (so that different user on same devices receives specific message not app wide). I have google cloud messaging working but I cant seem to figure out how to generate Registration ID so i can send a message to specific user

InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId ),
                GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);

If I am correct it generates here but how would I for example put user ID here (or where). Or did I misunderstood this entirely.

Upvotes: 0

Views: 165

Answers (2)

Rob Meeuwisse
Rob Meeuwisse

Reputation: 2937

You can use the topic messaging functionality from GCM.

Your server can send a GCM message to /topics/{userId} and your app should subscribe to the users that are using that device. Your app will then receive the GCM message with the from field set to the topic and your app can take it from there.

You do something like this in your GCM registration service:

InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId ),
            GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);

GcmPubSub pubSub = GcmPubSub.getInstance(this);
pubSub.subscribe(token, "/topics/user1", null);
pubSub.subscribe(token, "/topics/user2", null);

Note that you don't even need to send the GCM token to your backend service because it is never going to send GCM messages to particular devices, only to topics. Because your app subscribed to the corresponding topics it will receive those messages.

In your GCM onMessageReceived you just get the private message and the userId and store it somewhere.

public void onMessageReceived(String from, Bundle data) {
    final int topicsLength = "/topics/".length();
    String userId = from.substring(topicsLength);
    String privateMessage = data.getString("privateMessage");
    saveMessageSomewhere(userId, privateMessage);
}

Then when a user logs on your app they have their messages waiting for them.

Note that it is up to you to generate unique user IDs. You can have your app request one from your backend service, or you could just rely on UUID.randomUUID().

Update

Note that the GCM topic must conform to the specification: /topics/[a-zA-Z0-9-_.~%]+. I had mistakenly assumed path separators are allowed, but if you use something like /topics/users/user1 you will run into:

java.lang.IllegalArgumentException: Invalid topic name: /topics/users/user1

This is because of the path separator character in users/user1. GCM does not allow a hierarchy of topics such as you might have in a REST API.

I have updated the above sample code to avoid this mistake.

Upvotes: 1

Much Overflow
Much Overflow

Reputation: 3140

You cannot create gcm token yourself. It is generated per application and generated outside your app.

What you can do is to maintain intallation --> user & user-installation table in your database and send notification to all installed instances belonging to a particular user.

Upvotes: 1

Related Questions