为什么我可以通过 Google 云到设备消息传递服务为我的设备获得多个活动令牌?
我刚刚将 C2DM 功能添加到我的 Android 应用程序中。
目前,如果在我的应用程序中启动 C2DM,则会发生以下情况。
- 我的应用程序发送注册 Intent
- 我的应用程序收到应答广播
从 Intent 中检索设备令牌并将其发送到我的服务器
从那一刻起,一切都运转良好。客户端接收推送通知等。 如果发生以下情况,就会出现问题:
用户在未禁用推送的情况下卸载应用程序。 (完全删除而不只是更新)
- 用户重新安装应用程序
如果在步骤 5 之后发送推送通知,我的应用程序仍然收到此通知。 看来从以前的安装中检索到的令牌仍然处于活动状态,并且重新连接到我的应用程序的新实例。
这会导致以下问题:
- 重新安装我的应用程序但无意接收推送通知的用户无法将自己从服务中删除,因为应用程序的新实例无法从我的服务器取消注册旧令牌。
这是 C2DM 系统中的错误还是我的设置有问题?
更新
我遵循了 Berdon 的建议并执行了以下操作:
出于测试目的,仅在每次应用程序启动时启动注销 Intent。 发送取消注册意图后,我的服务器不会向我的应用程序发送推送通知。这似乎可以解决问题,但如果我现在进入 C2DM 设置屏幕并打开我的应用程序的推送通知,所有旧令牌都会再次激活,并且我会收到我在当前安装的应用程序中未注册的信息。
下一次更新
看来我不是唯一遇到这个问题的人:
我希望 Google 能够以一种方式管理这些令牌,即来自同一设备的旧令牌在新令牌后被禁用被发出。我还希望在发送取消注册意图后,该应用程序和该设备的所有令牌都被标记为无效或从 Google 服务器中永远删除。如果这是谷歌针对特殊用例的设计决定,我没有看到,请启发我。
I just added C2DM capability to my Android App.
At the moment the following happens if C2DM is started in my App.
- My App sends the registration Intent
- The answer broadcast is received by my app
The device token is retrieved from the intent and sent to my server
From that moment everything is working fine. The client receives the push notifications etc.
A problem occurs if the following hapens:The user uninstalls the application without disabling push. (Completely deleting it not only updating)
- The user reinstalls the application
If after step 5 a push notification is sent my app still receives this notification.
It seems that the token which was retrieved from the previous install is still active and is reconnected to the new instance of my application.
This leeds to the following problem:
- A user who reinstalls my app but has no intention of receiving push notifications has no possibility to remove himself from the service because the new instance of the app has no way to unregister the old token from my server.
Is this a bug in the C2DM system or is something wrong in my setup?
Update
I followed Berdons advice and did the following:
For testing purposes only start an unregister Intent every time my app starts up.
After I send the unregister intent no push notification from my server is sent to my application. That seems to do the trick, but if I now go the C2DM Settings Screen and turn on push notifications for my app all the old tokens get active again and I receive information that I did not register for in the current installation of my app.
Next Update
It seems I'm not the only one with this problem:
Android C2DM : Duplicate message to the same device and App
I hoped that Google would manage those tokens in a way that old tokens from the same device get disabled after a new one was issued. I also expect that after I sent an unregister Intent all tokens for that application and that device are marked as invalid or deleted from the Google Server for ever. If this is somehow a design decision by Google for special use cases I don't see please enlighten me.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
更像是一个意想不到的“功能”。您可以考虑在应用程序的“首次运行”(有史以来第一次运行)时发出取消注册请求,以防止发生这种情况。
更新
您可以使用 crash_key(或您自己创建的任何内容)作为标识符来区分不同的 C2DM 消息。在注册之间更新它,并在注册、取消注册和消息之后将其传递到设备。
More like an unexpected "feature". You might consider issuing an unregister request on the "first run" (first run ever) of your application to prevent this from occuring.
Update
You could could do the work of differentiating between different C2DM messages by using the collapse_key (or anything of your own creation) as an identifier. Update it between registrations and pass it to the device following registrations, unregistrations and messages.
我们现在找到了一个适用于大多数情况的解决方案。
服务器将 C2DM 注册 ID 添加为每个 C2D 消息的数据字段。
此解决方案使我们能够仅显示相关数据,而无需存储唯一的用户 ID。
We now found a solution that should work in most of the cases.
The server adds the C2DM registration id as a data field with every C2D Message.
This solution enables us to show only relevant data without the need to store a unique user id.
在我的 C2DM 实现中,每个用户的设备令牌都根据其 UDID 和应用程序的包名称(以及其他内容)保存在数据库中。 UDID 和包名称构成主键,这意味着该表可以列出来自同一设备 (UDID) 的多个应用程序。当用户运行特定应用程序时,系统会记录设备令牌,如果他们卸载并重新运行该应用程序,则会记录新设备令牌而不是旧设备令牌。我们还有一些列来记录该特定应用程序/设备组合的推送是否处于活动状态,以及用户启用/禁用了哪些类型的推送消息。
当发送特定应用程序的推送时,不会多次注册 UDID(因为这两个字段构成主键),因此只会使用最新的设备令牌。此外,我们的查询仅返回启用了推送消息的行。
此解决方案应该可以解决您的问题,因为它会阻止您将推送发送到两个设备令牌。我希望这有帮助!
In my C2DM implementation, each user's device token is saved in a database against their UDID and the package name of the app (among other things). The UDID and package name form the primary key, meaning that the table can list multiple apps from the same device (UDID). When a user runs a particular app, the device token is recorded, and if they uninstall and re-run the app, the new device token would be recorded over the old one. We also have columns to record whether push is active for that particular app/device combo, and which types of push messages the user has enabled/disabled.
When the time comes to send a push for a particular app, no UDID will be registered more than once (since these two fields form the primary key), and therefore only the latest device token will be used. Furthermore, our query only returns the rows that have push messages enabled.
This solution should solve your problem because it prevents you from sending the push to both device tokens. I hope this helps!