3

I am using Google Cloud Messaging with XMPP in order to have both downstream and upstream messages.

Only client side I get a token by doing this on a worker thread:

InstanceID instanceID = InstanceID.getInstance(this);

try {
    String token = instanceID.getToken(getString(R.string.gcm_senderID), GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);

    send_token(token, getString(R.string.gcm_senderID));
} catch (IOException e) {
    e.printStackTrace();
}

I then send this token over to the server where it is received. I am able to send messages to the client with this token.

Then I can send an upstream message on the client side with this:

new AsyncTask<Void, Void, String>() {
    @Override
    protected String doInBackground(Void... params) {
        String msg;

        Bundle data = new Bundle();

        data.putString("message", message);

        try {
            messenger.send(getString(R.string.gcm_senderID) + "@gcm.googleapis.com", messageId.addAndGet(1) + "", data);
        } catch (IOException e) {
            e.printStackTrace();
        }

        msg = "Sent message";

        return msg;
    }
}.execute(null, null, null);

In the upstream message sent from the client, there is a from field, that seems to be a token as well. If I send a message to this from the server side, my phone receives it as well.

What confuses me is that the token in the from field is not equal to the one generated by the InstanceID service.

The first 18 characters or so are equal, but after that they are very different. As such, is there a good way to identify what device sent what message?

I could store the token generated by the Instance ID each time in the Bundle, but I was wondering if there might be any way to make the from field of the upstream message be consistent with the generated ID.

Edit: Using the deprecated register function, I was able to get a consistent registration ID.

String token = GoogleCloudMessaging.getInstance().register(getString(R.string.gcm_senderID));

But is there a way to do this with InstanceID?

Clark
  • 1,357
  • 1
  • 7
  • 18
  • Upstream messaging still uses the GoogleCloudMessaging API to send messages so it is expected that it uses a GoogleCloudMessaging-generated registration ID as its source (the "from" object). At this point, it looks like adding the Instance ID token to the Bundle is the most convenient thing for you to do if you want your server to handle messaging in a uniform manner. – Koh Jun 09 '15 at 23:16
  • Yeah, it makes sense that it has a generated registration ID as its source, but I don't see why it uses a freshly generated registration ID for each upstream message sent, shouldn't it use the registration ID generated by the app? – Clark Jun 10 '15 at 12:52
  • The docs at https://developers.google.com/cloud-messaging/server-ref#upstream says this about the "from" field of an upstream XMPP message: "This parameter specifies who sent the message. **The value is the registration token of the client app.**" From this I understand it should be the same as what instanceID.getToken(GCM_SENDER_ID, GoogleCloudMessaging.INSTANCE_ID_SCOPE); returned, but it isn't. Every message has a different "from" except for the first 18 chars – Alex Bitek Jun 15 '15 at 15:49
  • @Clark Another alternative, instead of storing the token in the message itself: if you have your own authentication mechanism inside the app, you can find on the server the token of the user you are sending the message from by adding your own identifier in the upstream message and on the server you find the token based on that identifier. (Assuming you already sent the token to the server previously and associated it with the identifier and stored it somewhere) – Alex Bitek Jun 15 '15 at 15:53
  • I'm having the same issue. Seems like a bug to me. Have you found a solution? – palindrom Jun 30 '15 at 16:12
  • Unfortunately I haven't been able to find a solution as of yet. For now I'm just using the deprecated `register` function instead :( – Clark Jul 01 '15 at 19:30
  • The device i'm having the issue is api 16 and has cyanogenmod. Doesn't happen on a device with api 21 and stock rom. – palindrom Jul 02 '15 at 09:37
  • It's probably a cyanogenmod bug: https://stackoverflow.com/questions/30381091/issue-getting-gcm-id-on-phones-with-cyanogenmod – palindrom Jul 02 '15 at 09:45
  • Hmm, I'm having the issue on a Nexus 5 running api 22, it seems to work on API 21? – Clark Jul 02 '15 at 15:42
  • Yes, it works as expected on my Xperia z with api 21. – palindrom Jul 04 '15 at 14:10
  • Here is a similar question. This certainly does looks like a bug. http://stackoverflow.com/q/31227589/267540 – e4c5 Jul 27 '15 at 12:29

1 Answers1

0

Calling GoogleCloudMessaging.getInstance(context).register(senderId) instead of getToken(senderId, "GCM") seems to resolve the issue, the XMPP server will then receive the correct token, every time, in the "from" property of the upstream message.

My device is running CyanogenMod, so the Google Play services app doesn't update automatically. Since the old register() work, this issue is likely caused by a bug in the google-play-services_lib when talking to an older version of the GMS app.

I've answered instead of comment with the vain hopes of an Google dev seeing this.

ballzak
  • 701
  • 2
  • 6
  • 26