在 iOS 上获取 GCM 推送通知的注册令牌的正确顺序? GCM不可靠吗?
Posted
技术标签:
【中文标题】在 iOS 上获取 GCM 推送通知的注册令牌的正确顺序? GCM不可靠吗?【英文标题】:Proper sequence to get registration token for GCM push notification on iOS? Is GCM unreliable? 【发布时间】:2015-11-25 14:20:20 【问题描述】:您好,我已按照在 ios 上使用 GCM 的教程进行操作。它一直在间歇性地工作(这意味着所有的证书、权限和东西都可以)。但是最近,我反复收到两条错误消息:
GCM | GCM registration is not ready with auth credentials
.
此外,重新连接到 GCM 失败:
Error Domain=com.google.gcm Code=501 "(null)"
这在一定程度上与设备未获得 GCM 注册 ID 相关。最近有没有其他人更频繁地遇到这些问题?还是因为我以错误的顺序调用 GCM API(尤其是 connectWithHandler:
、startWithConfig:
和 tokenWithAuthorizedEntity
方法)?我怀疑原因是后者,因为我确实在延迟一段时间后获得了 GCM ID。
我也不总是收到 GCM ID。当我没有收到时,我通常必须通过 Xcode 再运行一次或两次该应用程序。 (或通过强制关闭应用程序)。显然,这不是我的用户应该做的事情。
这是我的 GCM API 调用顺序:
-
设备获得 APNS 令牌
然后我打电话给
tokenWithAuthorizedEntity:
使用我的 APNS 令牌
^ 这通常是
导致上述两个错误之一。
每当我
实际上需要一个 GCM 令牌,我强制重新获取 GCM 令牌
再次致电tokenWithAuthorizedEntity
。
另外,我的 applicationDidBecomeActive:
方法中也写了 connectWithHandler:
调用。
几个问题:
-
如果我只对接收 GCM 推送消息感兴趣并且不向上游发送它们,是否有必要在
applicationDidBecomeActive:
中调用 connectWithHandler:
?
如果对 (1) 的回答是肯定的,在该方法的完成处理程序中,如果发生错误,并且此时我没有 GCM 令牌,我是否应该再次尝试获取令牌? (即致电tokenWithAuthorizedEntity
?)
什么时候应该调用startWithConfig
?在获得 GCM 令牌之前还是之后?
编辑:有限的测试表明以下似乎有效:
-
先获取 GGLInstance ID(即调用
getIDWithHandler:
)
如果收到上述 GGLInstance ID 且没有任何错误,请索要 GCM 令牌(即致电 tokenWithAuthorizedEntity:
)
这样做通常会产生以下错误,但至少在短时间内(~3-10 秒),令牌被收到:
无法在缓存中找到令牌错误域=com.google.iid 代码=-25300 “(空)”
【问题讨论】:
我在 iOS 上使用 GCM,因为我认为它让事情变得非常简单。虽然我还没有遇到这些错误。发布您的注册码,我将与我的比较 如果您遵循了谷歌的 GCM 示例,您不会真的出错,请查看您正在使用的证书并确保这些证书对于身份验证凭据错误是正确的。 什么身份验证错误?如果出现证书错误,那么推送一开始就不会起作用。 对于上述错误,我建议您按照文档中的建议实施重试机制,如果问题没有消失,请将其报告给支持渠道之一。在此处查看 5xx 错误的描述:developers.google.com/cloud-messaging/…. 【参考方案1】:是在applicationDidBecomeActive中调用connectWithHandler: 如果我只对接收 GCM 推送消息感兴趣并且 不向上游发送?
是的,connectWithHandler 是必需的,因为它的主要目的是与 GCM 端点建立连接。
如果对 (1) 的回答是肯定的,则在该方法的完成处理程序中,如果 发生错误,我当时没有 GCM 令牌,应该 我尝试再次获得令牌? (即调用 tokenWithAuthorizedEntity?)
因此,它的工作方式是在请求令牌本身时检查错误,如果请求失败,则使用指数回退重试。更多信息here。另外,请阅读注释here。现在,如果您仍然想在任何时候重新调用GGLInstanceIDTokenHandler
,您还应该在获取新令牌之前实现deleteTokenWithAuthorizedEntity
。
什么时候应该调用 startWithConfig?在获得 GCM 令牌之前 还是之后?
在您的AppDelegate.m
中,您应该使用startWithConfig
方法调用GGLInstanceID
共享实例。本质上在GGLINstanceID.h
类中,它应该首先获取一个Instance ID;然后将项目授权为授权实体,然后通过 iid 服务获取注册令牌。请参阅GGLInstanceID.h
类here 的详细实现。
希望这个答案有所帮助!
编辑
this 会回答您的问题吗?要点是,确保目标的 Bundle Identifier 与 info.plist 文件中的 BUNDLE_ID 相同。
希望这可以解决错误,如果没有发布您测试时发生的情况,我们可以从那里开始。 :)
【讨论】:
你的意思是说这些东西应该是严格顺序的吗?:1)获取GGLInstance ID(通过getIDWithHandler:
) 2)然后调用tokenWithAuthorizedEntity:
? (这意味着只有在 (1) 中成功获取实例 ID 时,我才必须在 (1) 的完成处理程序中调用 (2))
我不太确定订单的严格性,但从逻辑上讲,GGLInstanceID 是您获取令牌之前必须的,因为此令牌是通过实例 ID 服务生成的,除非应用实例初始化此实例 ID ,它应该如何分配一个令牌?
关于 TokenWithAuthorizedIdentity;我不能肯定地评论它应该落在哪里,但是在设备检索令牌之前,AFAIK 项目身份验证也很重要。
总而言之,根据我的理解:注册令牌将具有与特定设备上特定项目的应用程序实例相对应的此类身份验证凭据。请注意,GCM 必须在“abc”设备上为应用程序的“第一个”实例识别“xyz”项目;以便它可以将通知传递到其确切的目的地。我希望这是有道理的。
好的,是的,这是有道理的。同时我会继续测试它并在这里报告。【参考方案2】:
得到gcmConfig块后,尝试将connectWithHandler块移到didFinishLaunchingWithOptions方法中。(官方示例,在[END start_gcm_service]之后)
【讨论】:
以上是关于在 iOS 上获取 GCM 推送通知的注册令牌的正确顺序? GCM不可靠吗?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Java GCM API 在 android 设备上获取失败推送通知的注册 ID