识别上行GCM消息的发送者

3
我将使用Google Cloud Messaging和XMPP来实现下行和上行消息的传输。仅在客户端,我通过以下方式在线程中生成一个令牌:
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();
}

我将这个令牌发送到接收方服务器,然后可以使用该令牌向客户端发送消息。
然后,我可以在客户端使用以下内容发送上行消息:
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);

在客户端发送的上行消息中,有一个名为from的字段,看起来也是一个令牌。如果我从服务器端向此处发送一条消息,则我的手机也会收到该消息。
让我感到困惑的是from字段中的令牌与InstanceID服务生成的令牌不相等。
前18个字符左右是相同的,但之后它们非常不同。因此,是否有一种好的方法来识别哪个设备发送了什么消息?
我可以将每次由Instance ID生成的令牌存储在Bundle中,但我想知道是否有任何方法使上行消息的from字段与生成的ID一致。
编辑:使用已弃用的register函数,我能够获得一致的注册ID。
String token = GoogleCloudMessaging.getInstance().register(getString(R.string.gcm_senderID));

但是使用InstanceID有没有办法做到这一点呢?

是的,使用生成的注册ID作为源是有道理的,但我不明白为什么每次发送上游消息时都要使用新生成的注册ID,难道不应该使用应用程序生成的注册ID吗? - Clark
在 https://developers.google.com/cloud-messaging/server-ref#upstream 的文档中提到了关于上行 XMPP 消息的 "from" 字段的信息:"此参数指定了谁发送了消息。该值是客户端应用程序的注册令牌。" 从这个描述中,我理解它应该与 instanceID.getToken(GCM_SENDER_ID, GoogleCloudMessaging.INSTANCE_ID_SCOPE) 返回的值相同,但实际上并不是这样的。每条消息的 "from" 字段都不同,除了前18个字符。 - Alex Bitek
@Clark 另一种选择是,在消息本身中不存储令牌:如果您在应用程序内部拥有自己的身份验证机制,则可以通过在上行消息中添加您自己的标识符来查找发送消息的用户的令牌,然后在服务器上根据该标识符找到令牌。(假设您已经先前将令牌发送到服务器并将其与标识符关联并将其存储在某个地方) - Alex Bitek
很遗憾,目前我还没有找到解决方案。现在我只能使用已弃用的 register 函数了 :( - Clark
是的,在我的Xperia z上,使用API 21可以正常工作。 - palindrom
显示剩余6条评论
1个回答

0

调用GoogleCloudMessaging.getInstance(context).register(senderId)而不是getToken(senderId, "GCM")似乎解决了这个问题,XMPP服务器将会在上行消息的“from”属性中每次接收到正确的令牌。

我的设备正在运行CyanogenMod,因此Google Play服务应用程序不会自动更新。由于旧的register()方法可以工作,所以这个问题很可能是google-play-services_lib与旧版本的GMS应用程序通信时出现的错误。

我已经回答了,而不是评论,希望有Google开发人员能看到这个问题。


谷歌已经承认他们有一个未解决的问题,并正在努力解决。 - ballzak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接