GCM 推送通知的问题
Issues with GCM Push Notifications
关于 Whosebug 的第一个问题,我将询问 Google 云消息服务,特别是 Loopback 的实施。
所以,我正在开发一个应用程序,并开始在不同的分支上工作,以介绍 Loopback 的推送通知处理和它的各种 REST 工具 Api。即使本主题将严格涵盖 Loopback 处理 GCM 的方式,该问题也与 Google 文档中描述的原始方式有关。
因此,GCM kick-off 背后的主要思想是检查设备是否已注册。
这是通过简单检查 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 中的值处理的方式)
假设每次创建我的 MainActivity 时都会执行此“GCM-Check”(因此,在 onCreate 方法期间)。
我们也知道 GCM 有时很乱,想要刷新我的应用程序的 RegistrationId 或其他一些东西,老实说,我现在还不是很清楚。简而言之,GCM 使我的应用程序的令牌无效。当服务器使用绑定到我的 device-app.
的令牌发送 push-notification 时,这会导致 error-message
类似于
的错误
{"multicast_id":0123456789012345678,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"NotRegistered"}]}
你可以看到,"failure":1
和"results":[{"error":"NotRegistered"}]
Loopback 的反应正如 Google 文档所说,通过让服务器删除链接到错误 RegistrationId 的设备的记录。
看得懂。
回到我们的设备。再次启动我的应用程序并加载 MainActivity,会导致相同的“GCM-check”过程。这次应用程序可以使用 SharedPreferences 找到 RegistrationId,并可以直接通知服务器,服务器根据给定的 RegistrationId 创建一条记录。
device-app没有处理新的注册。
你可以在这里看到循环。设备将不知道它的令牌无效,并将继续告诉服务器相同的数据,服务器将不断向错误的 registrationId 发送信息,从而在收到相关错误后将其删除。
问题在于应用程序必须依赖一次创建且永远不会被修改的数据。要删除旧数据,我应该向设备发送通知,这显然是不可能的,因为我无法从 GCM 访问它。其他可能的解决方案是通过发送电子邮件或短信通知用户,并要求他单击按钮,但我宁愿采用更“自动化”的方法来解决问题。
我找到了一个非常糟糕的解决方案
据我所知,只有 error-info 是在 push-notification 期间从 GCM 返回到服务器的,我对设备进行了一些修改。
想法很简单:创建一个 POST 请求到 GCM 服务器,使用 headers 我的服务器应该用来进行身份验证。这导致错误被提供给设备本身,它可以解析 JSON 并注意到发生了什么。应用程序可以从这里建立一个新的注册过程,解决这个问题。
这有什么不好? 事实上,要将设备验证为服务器,我必须 hard-code ServerKey 并将其分发到每个应用程序中。 ServerKey 应该只在服务器上使用,使这个解决方案成为一个非常糟糕的主意。
也就是说,使用 SharedPreference 值简单地让设备知道其状态的想法并不是很好,因为它只会告诉我是否至少注册过一次,而不会让我知道我的当前状态。
在我开发的其他也使用 GCM 的应用程序上,我用不同的方式解决了问题,比如让用户单击按钮或读取服务器发送的一些特殊短信,然后启用GoogleCloudMessaging.unregister() at first and eventually GoogleCloudMessaging.register()
所以,对于这样的wall-of-text请见谅,你是怎么解决这个NotRegistered的事情的?
感谢您的努力和时间阅读,希望您能回答:)
作为我评论的补充,因为它有帮助,我在这里有更多 space:
除了检查令牌是否存在于您的 SharedPreferences 中之外,您还应该检查令牌所针对的应用程序版本是否与当前 运行 检查的版本相匹配(即是 Google 文档的建议)。
如果设备版本不匹配,您应该请求一个有效的令牌(实际上可能相同,但不能保证)。现在,您可能还想检查 PACKAGE_REPLACED 广播(如果您每次安装测试时都没有增加清单中的版本,我对此感到非常内疚),如果被触发,应该还强制您请求新令牌。
至于为什么令牌有时会发生变化,有时却不会:我完全同意这完全是零星的,并且不禁觉得好像发生了一些我们并不真正了解的事情。
有时新的请求在PACKAGE_REPLACEDreturns相同的key之后;有时它没有。在使它变得奇怪的那些之间发生了什么?上帝,我很想知道,我希望我有更多关于它的信息。但这就是我提到尝试捕获该广播的部分原因:在它发生时强制进行检查应该确保您始终获得一个新的有效版本(如果版本检查在不应该通过的情况下通过)(如果它可用)。
希望对你有所帮助~
关于 Whosebug 的第一个问题,我将询问 Google 云消息服务,特别是 Loopback 的实施。
所以,我正在开发一个应用程序,并开始在不同的分支上工作,以介绍 Loopback 的推送通知处理和它的各种 REST 工具 Api。即使本主题将严格涵盖 Loopback 处理 GCM 的方式,该问题也与 Google 文档中描述的原始方式有关。
因此,GCM kick-off 背后的主要思想是检查设备是否已注册。
这是通过简单检查 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 中的值处理的方式)
假设每次创建我的 MainActivity 时都会执行此“GCM-Check”(因此,在 onCreate 方法期间)。
我们也知道 GCM 有时很乱,想要刷新我的应用程序的 RegistrationId 或其他一些东西,老实说,我现在还不是很清楚。简而言之,GCM 使我的应用程序的令牌无效。当服务器使用绑定到我的 device-app.
的令牌发送 push-notification 时,这会导致 error-message类似于
的错误{"multicast_id":0123456789012345678,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"NotRegistered"}]}
你可以看到,"failure":1
和"results":[{"error":"NotRegistered"}]
Loopback 的反应正如 Google 文档所说,通过让服务器删除链接到错误 RegistrationId 的设备的记录。 看得懂。
回到我们的设备。再次启动我的应用程序并加载 MainActivity,会导致相同的“GCM-check”过程。这次应用程序可以使用 SharedPreferences 找到 RegistrationId,并可以直接通知服务器,服务器根据给定的 RegistrationId 创建一条记录。
device-app没有处理新的注册。
你可以在这里看到循环。设备将不知道它的令牌无效,并将继续告诉服务器相同的数据,服务器将不断向错误的 registrationId 发送信息,从而在收到相关错误后将其删除。
问题在于应用程序必须依赖一次创建且永远不会被修改的数据。要删除旧数据,我应该向设备发送通知,这显然是不可能的,因为我无法从 GCM 访问它。其他可能的解决方案是通过发送电子邮件或短信通知用户,并要求他单击按钮,但我宁愿采用更“自动化”的方法来解决问题。
我找到了一个非常糟糕的解决方案
据我所知,只有 error-info 是在 push-notification 期间从 GCM 返回到服务器的,我对设备进行了一些修改。
想法很简单:创建一个 POST 请求到 GCM 服务器,使用 headers 我的服务器应该用来进行身份验证。这导致错误被提供给设备本身,它可以解析 JSON 并注意到发生了什么。应用程序可以从这里建立一个新的注册过程,解决这个问题。
这有什么不好? 事实上,要将设备验证为服务器,我必须 hard-code ServerKey 并将其分发到每个应用程序中。 ServerKey 应该只在服务器上使用,使这个解决方案成为一个非常糟糕的主意。
也就是说,使用 SharedPreference 值简单地让设备知道其状态的想法并不是很好,因为它只会告诉我是否至少注册过一次,而不会让我知道我的当前状态。
在我开发的其他也使用 GCM 的应用程序上,我用不同的方式解决了问题,比如让用户单击按钮或读取服务器发送的一些特殊短信,然后启用GoogleCloudMessaging.unregister() at first and eventually GoogleCloudMessaging.register()
所以,对于这样的wall-of-text请见谅,你是怎么解决这个NotRegistered的事情的?
感谢您的努力和时间阅读,希望您能回答:)
作为我评论的补充,因为它有帮助,我在这里有更多 space:
除了检查令牌是否存在于您的 SharedPreferences 中之外,您还应该检查令牌所针对的应用程序版本是否与当前 运行 检查的版本相匹配(即是 Google 文档的建议)。
如果设备版本不匹配,您应该请求一个有效的令牌(实际上可能相同,但不能保证)。现在,您可能还想检查 PACKAGE_REPLACED 广播(如果您每次安装测试时都没有增加清单中的版本,我对此感到非常内疚),如果被触发,应该还强制您请求新令牌。
至于为什么令牌有时会发生变化,有时却不会:我完全同意这完全是零星的,并且不禁觉得好像发生了一些我们并不真正了解的事情。
有时新的请求在PACKAGE_REPLACEDreturns相同的key之后;有时它没有。在使它变得奇怪的那些之间发生了什么?上帝,我很想知道,我希望我有更多关于它的信息。但这就是我提到尝试捕获该广播的部分原因:在它发生时强制进行检查应该确保您始终获得一个新的有效版本(如果版本检查在不应该通过的情况下通过)(如果它可用)。
希望对你有所帮助~