处理多个设备,同一用户的GCM注册ID

时间:2014-08-05 13:18:59

标签: android push-notification google-cloud-messaging

这是很多应用程序所面临的常见情况,但我仍在努力了解如何实施:

让我们说我的应用程序是一个拥有当前登录用户的社交网络。 我想向当前用户登录的所有设备发送GCM消息给该用户。

这意味着我的服务器为每个用户提供了所有注册ID的列表 - 每个用户的一个注册ID。

问题:如何才能唯一地跟踪他的每个设备? seems there is no reliable way to get specific device identifier

不存储每个独特设备的注册ID - 我不知道如何管理它。

当用户将卸载/注销并随后获得新的注册ID时,事情变得混乱,这假设要替换现有的已知id之一,但是哪一个?

如果我喜欢只向特定设备发送消息而不是所有设备,那么事情会变得更加棘手...

请帮助我了解我遗漏的内容,以及为同一用户处理多个设备注册ID的正确方法。

3 个答案:

答案 0 :(得分:6)

Google在处理GCM时会为您处理所有艰苦的工作。他们提供了一种简单的方法来始终使注册ID保持最新。每封发送的消息都有一个名为canonicalRegistrationId的额外字段。如果该字段中有id,则注册ID已更改并需要更新。每个消息都存在此字段,每次发送一个消息时,都必须检查该字段。如果有新canonicalRegistrationId,那么您应该尽快更新registrationId。旧的可能会继续工作一段时间,但没有告诉它何时变得无效。

例如,在Google App Engine后端,处理更改注册ID的代码看起来像这样:

// We want to send a message to some devices
// Get registered devices and then loop through them
List<RegistrationRecord> records = ofy().load().type(RegistrationRecord.class).limit(10).list();
for(RegistrationRecord record : records) {

    // Send the message to one device
    Result result = sender.send(msg, record.getRegId(), 5);

    // If the messageId is not null, then the message has been sent successfully
    if (result.getMessageId() != null) {
        log.info("Message sent to " + record.getRegId());

        // Check for canonical message id
        // If it is not null, then the registrationId has changed
        String canonicalRegId = result.getCanonicalRegistrationId();
        if (canonicalRegId != null) {

            // The registrationId has changed! We need to update it in the database
            log.info("Registration Id changed for " + record.getRegId() + " updating to " + canonicalRegId);
            record.setRegId(canonicalRegId);
            ofy().save().entity(record).now();
        }
    } else {
        ... // Irrelevant error handling
    }
}

所以你需要做的很简单:每次发送邮件时,检查是否有canonicalRegistrationId,如果是,则用规范更新旧的registrationId。

答案 1 :(得分:1)

我认为您必须获取设备IMEI否并将其保存到具有注册ID的服务器,并且当用户使用其他设备重新注册他自己时,然后获取检查IMEI号将其替换为旧的。主要的东西现在在旧设备检查中发送IMEI否与消息和IF IMEI否是匹配然后没有问题否则阻止应用程序。并通知用户...

多数民众赞成......

答案 2 :(得分:1)

Google支持设备群组消息传递。请参阅此链接:https://developers.google.com/cloud-messaging/notifications#managing_device_groups

要处理多个用户,您可以为该用户创建一个组,并将注册ID添加到该组。要创建组,请向https://android.googleapis.com/gcm/notification发送如下请求:

Content-Type:application/json Authorization:key=API_KEY project_id:SENDER_ID

{ "operation": "create", "notification_key_name": "appUser-Chris", "registration_ids": ["4", "8", "15", "16", "23", "42"] }

此API返回响应中的通知密钥,您可以将其存储在数据库中,稍后用于向该组发送通知。随后,只要用户登录到其他设备,您就可以获得该设备的reg_id并将其添加到该组中。要将注册ID为51的设备添加到appUser-Chris,您需要发送此请求:

{ "operation": "add", "notification_key_name": "appUser-Chris", "notification_key": "aUniqueKey", "registration_ids": ["51"] }

当用户退出设备时,您可以从群组中删除reg_id

向群组发送通知与向注册ID发送通知相同。

我在这里观察到的一个问题是,如果在创建组时未能将notification_key存储到数据库中,则无法再次获取它。并且无法再为同一notification_key_name创建新组。解决此问题的方法是明智地选择notification_key_name。因此,当您无法存储notification_key并再次尝试创建具有相同noitification_key_name的组时,您将收到错误消息。在这种情况下,您只需更改该用户的notification_key_name并创建一个新组即可。希望这会有所帮助。