GCM推送通知的问题

时间:2015-03-09 15:28:28

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

关于StackOverflow的第一个问题我将问一下Google Cloud Messaging服务,特别是Loopback的实现。

所以,我正在开发一个应用程序,并开始在另一个分支上工作,介绍Loopback的推送通知处理及其针对REST Api的各种工具。即使这个主题将严格涵盖Loopback处理GCM的方式,但问题也与Google文档中描述的原始方式有关。

因此,GCM启动背后的主要思想是检查设备是否已注册。

这是通过简单检查SharedPreferences变量来完成的,该变量是用于存储我们的RegistrationID值的名称。

final LocalInstallation installation = new LocalInstallation(context, adapter);

如果找到,设备必须通知服务器,并传送令牌。 否则,必须完成GCM的注册。 完成此操作后,设备会通知服务器。 (registerInBackground(installation)最终会在检索RegistrationId后调用saveInstallation(installation)

    if (installation.getDeviceToken() != null) {
        saveInstallation(installation);
    } else {
        registerInBackground(installation);
    }

如果通信成功,设备将使用SharedPreferences保存RegistrationId,如上所述。 (注意:getDeviceToken()是Loopback通过API处理SharedPreferences中的值的方法)

让我们说这" GCM-Check"每次创建MainActivity时都会这样做(因此,在onCreate方法中)。

我们也知道GCM有时会很乱,并且想要刷新我的应用程序的RegistrationId或其他一些事实,现在对我来说并不完全清楚。简而言之,GCM使我的应用程序的令牌无效。当服务器使用绑定到我的设备应用程序的令牌发送推送通知时,这会导致错误消息。

类似于

的错误
{"multicast_id":0123456789012345678,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"NotRegistered"}]}

您可以看到"failure":1"results":[{"error":"NotRegistered"}]

Loopback的反应正如Google文档所说,让服务器删除链接到错误RegistrationId的设备的记录。 理解的。

返回我们的设备。再次启动我的应用程序并加载MainActivity,会导致相同的" GCM检查"程序。这次app可以使用SharedPreferences找到RegistrationId,并且可以直接通知服务器,服务器使用给定的RegistrationId创建记录。

设备应用无法处理新的注册。

你可以在这里看到循环。设备将不知道它的令牌无效,并将继续告诉服务器相同的数据,这将继续向错误的registrationId发送信息,从而在收到相关错误后将其删除。

问题是应用程序必须依赖于创建一次且永远不会被修改的数据。要删除旧数据,我应该向设备发送通知,这显然是不可能的,因为我无法从GCM到达它。其他可能的解决方案是通过发送电子邮件或短信通知用户,并要求他点击一个按钮,但我宁愿有更多的自动化"处理问题。


我找到了一个非常糟糕的解决方案

据我所知,在推送通知期间,唯一的错误信息从GCM返回到服务器,我已经对该设备进行了一些破解。

这个想法很简单:使用我的服务器用来进行身份验证的标头,向GCM服务器创建一个POST请求。这会导致错误被赋予设备本身,它可以解析JSON并注意发生了什么。从这里,该应用程序可以打造一个新的注册过程,解决问题。

这有什么不好?要将设备作为服务器进行身份验证,我必须对ServerKey进行硬编码并将其分发到每个应用程序中。 ServerKey只能在服务器上使用,这使得这个解决方案成为一个非常糟糕的主意。


话虽如此,简单地让设备使用SharedPreference值知道其状态的想法并不是那么好,因为它只会告诉我是否至少注册过一次,而不让我知道我当前的状态。

在我开发的其他使用GCM的应用程序中,我已经用不同的方式解决了,比如用户点击按钮或者阅读服务器发送的一些特殊短信,然后首先启用GoogleCloudMessaging.unregister(),最后启用GoogleCloudMessaging.register()


所以,请求原谅这样的文本墙,你是如何解决这个NotRegistered的事情的呢?

感谢您的努力和阅读时间,并希望能够回答:)

1 个答案:

答案 0 :(得分:1)

作为我评论的附录,因为它有所帮助,我在这里有更多空间:

除了检查令牌是否存在于您的SharedPreferences中之外,您还应该检查您的应用程序的那个令牌的版本是否与当前运行检查的版本相匹配(这是来自Google的建议&# 39; s docs)。

如果设备版本不匹配,您应该请求一个有效的令牌(实际上可能是相同的,但不能保证)。现在,您可能还想检查PACKAGE_REPLACED广播(如果您每次安装测试时都没有增加清单中的版本,我非常内疚),如果触发,应该还强迫您申请新令牌。

至于为什么有时会改变代币,有时候不会改变:我不能同意它完全是零星的,并且不能帮助感觉像那里一样。正在发生的事情,我们真的不知道。

有时PACKAGE_REPLACED之后的新请求会返回相同的密钥;有时它不会。在那些让它变得怪异的人之间会发生什么?上帝,我很乐意知道,我希望我有更多信息。但这就是为什么我提到试图捕捉广播的部分原因:强制检查发生的时候应该确保你总是得到一个新的有效广告(如果版本检查在不应该的时候通过&#&# 39; t)是否可用。

希望这会有所帮助〜