GCM 令牌何时过期以及 InstanceID 是什么?

When do GCM Tokens Expire and What is the InstanceID?

由于 GCM 不断更新,我搜索过的大部分资源似乎都已过时或不清楚。基本上,我对令牌和 ID 何时过期感到困惑。 (作为参考,我正在使用 Android。)

据我了解(如果我错了请纠正我),我的服务器有一个 API 密钥和一个发件人 ID。使用发件人 ID,我可以让我的客户通过本地存储在我的客户端上的 InstanceID 请求令牌。我在这里已经有点困惑了。 InstanceID 是在我的应用程序上线时分配的吗?它会改变吗?当应用程序升级或卸载并重新安装(或设备恢复)时怎么办?通过调用 InstanceID.getInstance,我会始终检索到相同的 InstanceID,还是它最终会过期并给我一个新的?存储通过调用 getID() 检索到的字符串是否有任何价值?文档似乎表明您在调用 getID() 时实际上检索了一个新的 InstanceID,因此这使事情变得更加复杂。 (作为参考,我指的是:https://developers.google.com/instance-id/

使用 InstanceID,我的客户端可以从 GCM 服务器请求令牌,然后将其发送到我的应用程序服务器。我的应用程序服务器存储这个令牌,并可以使用它向 GCM 服务器发送消息,然后 GCM 服务器将消息发送到设备。我相信,设备使用存储的 InstanceID 实际接收这些消息。因此,拥有一个扩展 GcmListenerService 的 class 将允许我使用 onMessageReceived 接收这些消息?我不需要做任何特别的事情(除了在 AndroidManifest 中定义它之外)?我不必实际告诉它使用 InstanceID?它只是神奇地知道?

这些 ID 和令牌什么时候过期?它们会过期吗?我将令牌作为字符串存储在服务器上,但如果其中任何一个过期,我怎么知道它们已经过期?我总是可以生成一个新的 InstanceID 和 Token,这看起来很容易,但是旧的仍然有效吗?如何从服务器上擦除旧令牌?在 iOS 方面似乎有一种简单的方法可以使用 APNS 执行此操作,您可以在其中检索所有过期令牌的列表,然后将它们从数据库中删除。

在更新我的 GCM 实施时,我发现自己会问其中的大部分问题。折腾了几天后,这是我对你的问题的看法。

From what I understand (and please correct me if I'm wrong), my server has an API Key and a Sender ID. Using the Sender ID I can have my client request a Token via the InstanceID stored locally on my client.

这是正确的。

The InstanceID is assigned the moment my app goes online?

它似乎是在您的应用启动后立即分配的,即使设备无法访问互联网也是如此。

Does it ever change? What about when the app upgrades or is uninstalled and reinstalled (or the device is restored)? By calling InstanceID.getInstance will I always retrieve the same InstanceID, or will it eventually expire and give me a new one?

根据 InstanceID documentation:

Instance ID is stable but may become invalid, if:

  • App deletes Instance ID
  • Device is factory reset
  • User uninstalls the app
  • User clears app data

If Instance ID has become invalid, the app can call getId() to request a new Instance ID.

我已经测试了卸载应用程序并清除数据,结果表明上述所有情况都是正确的。

Is there any value to storing the string you retrieve by calling getID()?

看起来 API 负责为您将其存储在应用程序的本地存储中。

Using the InstanceID, my client can request a Token from the GCM servers, which it then sends to my app server. My app server stores this Token, and can use this to send messages to the GCM servers, which will then send the message to the device. The device uses the stored InstanceID to actually receive these messages, I believe. So having a class that extends GcmListenerService will allow me to receive these messages with onMessageReceived? I don't have to do anything special (other than defining it in the AndroidManifest)? I don't have to actually tell it to use the InstanceID? It just magically knows?

据我所知,在以前的实现中没有任何类型的 InstanceId,而且看起来也没有在这个实现中明确使用它。如果是,则在 GcmReceiver or GcmListenerService.

中调用它

When do these ID's and Tokens expire? Do they expire?

我已经解决了 ID 的过期问题,我们可以在 Android InstanceID implementation guide:

中找到有关令牌过期的信息

The Instance ID service initiates callbacks periodically (for example, every 6 months), requesting that your app refreshes its tokens. It may also initiate callbacks when:

  • There are security issues; for example, SSL or platform issues.
  • Device information is no longer valid; for example, backup and restore.
  • The Instance ID service is otherwise affected.

指南说子类化 InstanceIDListenerService 并覆盖 onTokenRefresh() 来处理这些情况。

I store the Token as a string on the server, but if at any point one of these expires, how do I know they have expired?

guide for implementing GCM on your server 表示 GCM 服务器将使用有关您用于尝试发送推送通知的令牌的一些信息来响应您的服务器。

I can always generate a new InstanceID and Token, that much seems easy, but then do the old ones stay active?

我的测试表明是的,确实如此。

How do I wipe the old tokens from the server? There seems to be an easy way to do this with APNS on the iOS side of things, where you can retrieve a list of all the expired tokens and just wipe them from your database.

我仍在调查这个问题,如果我能弄明白的话会更新。

这是我检测数据库中无效标记的方法。

在向 user/list 用户发送通知时,GCM 中有一个 dry run 选项。当您在发送通知时设置 dry-运行 时,它不会提醒客户或向他们显示通知,而是 returns 响应哪些令牌有效(200)哪些无效。

如果您使用 dry-运行 选项向 200 个用户发送通知,那么您将按照相同的顺序从 GCM 收到响应。

什么是实例 ID?

实例 ID 为您的应用程序的每个实例提供一个唯一的 ID。您可以为 Android 和 iOS 应用以及 Chrome apps/extensions.

实施实例 ID

除了提供用于身份验证的唯一 ID 之外,实例 ID 还可以生成安全令牌以用于其他服务。

主要特点

  • 生成安全令牌
  • 验证应用真实性
  • 确认应用设备处于活动状态
  • 识别和跟踪应用程序

实例 ID 生命周期

  1. 当您的应用上线时,实例 ID 服务会发出一个 InstanceID。 InstanceID 由 public/private 密钥对支持,私钥存储在本地设备上,public 密钥已注册到 Instance ID 服务。
  2. 您的应用可以在需要时使用 getID() 方法请求新的 InstanceID。如果您的应用程序支持您的应用程序,则您的应用程序可以将其存储在您的服务器上。
  3. 您的应用可以根据需要使用 getToken() 方法从实例 ID 服务请求令牌,并且与 InstanceID 一样,您的应用也可以将令牌存储在您自己的服务器上。颁发给您的应用的所有令牌都属于该应用的 InstanceID。
  4. 令牌是唯一且安全的,但您的应用或实例 ID 服务可能需要在出现安全问题或用户在设备恢复期间卸载并重新安装您的应用时刷新令牌。您的应用程序必须实施侦听器以响应来自实例 ID 服务的令牌刷新请求。

Instance ID什么时候失效?

  • 应用程序删除实例 ID
  • 设备已恢复出厂设置
  • 用户卸载应用程序
  • 用户清除应用数据

如果Instance ID失效,应用可以调用getId()请求一个新的Instance ID。要证明实例 ID 的所有权并允许服务器访问与应用关联的数据或服务,请调用 getToken(String, String)。

什么时候刷新令牌?

实例 ID 服务会定期(例如,每 6 个月)发起回调,请求您的应用刷新其令牌。它也可能在以下情况下发起回调:

存在安全问题;例如,SSL 或平台问题。 设备信息不再有效;例如,备份和恢复。 实例 ID 服务会受到其他影响。

您需要了解的有关实例 ID 的所有信息都可以在以下官方链接中找到: