Firebase 云消息传递 - 如何验证令牌?

Posted

技术标签:

【中文标题】Firebase 云消息传递 - 如何验证令牌?【英文标题】:Firebase Cloud Messaging - How to validate Tokens? 【发布时间】:2016-07-18 17:10:58 【问题描述】:

我正在使用 Firebase Cloud Messaging (FCM),并且每次在客户设备上生成新令牌时,都会按照下面的缩写代码...我将这个新令牌发送到我的 SERVER DB(云),并按顺序保存它以便能够使用 CFM API 从服务器向设备发送未来的推送通知

    //public class CFMInstanceIDService extends FirebaseInstanceIdService ...

    public void onTokenRefresh() 
        ...
        String cfmToken = FirebaseInstanceId.getInstance().getToken();        
        ...     
        sendRegistrationToServer(customerGuid, cfmToken);
    

通过这样做,我在服务器上有一个客户登录的所有(多个)设备的列表。 (平板电脑、手机、iPhone、android 等)

有什么方法可以随时验证/验证令牌吗?

我想知道/确保我与客户关联的所有令牌都属于真实设备。我不想向不存在的令牌发送推送通知。

【问题讨论】:

【参考方案1】:

这是一个 curl 请求示例,展示了如何验证令牌而无需实际发送消息:

curl -H "Content-Type: application/json" -H "Authorization: key=$FCM_API_KEY" https://fcm.googleapis.com/fcm/send -d '"registration_ids":["$FCMTOKEN"]'

无效响应示例:

"multicast_id":7452350602151058088,"success":0,"failure":1,"canonical_ids":0,"results":["error":"InvalidRegistration"]

有效响应示例:

"multicast_id":9133870199216310277,"success":1,"failure":0,"canonical_ids":0,"results":["message_id":"0:1502817580237626%f590ddc2f9fd7ecd"]

我从 google 的 firebase 支持团队得到了这个答案。

【讨论】:

发布的答案实际上确实发送了一条消息;至少它对我的 ios 设备有影响。请求中包含“dry_run”:true表示不发送消息 失败时如何获取注册令牌ID?现在,我们只能收到错误和message_id等响应。但我也需要注册令牌 ID。请尽快回复。 @sameer 您将在响应中获得结果信息(数组字典)。数组响应中的每个字典项表示批量请求中每个设备令牌的状态(与您发送的顺序相同)。如果任何字典中的错误为“NotRegistered”,您可以通过匹配索引获取相应的令牌并将其从数据库中删除。【参考方案2】:

其实有一个变通方法,可以使用dry_run = true

此参数设置为 true 时,允许开发人员在不实际发送消息的情况下测试请求。

firebase docs

如果用户取消订阅,您会收到NotRegistered 的回复,但不会执行真正的发送

【讨论】:

使用 curl:curl -H "Content-Type: application/json" -H "Authorization: key=$FCM_API_KEY" https://fcm.googleapis.com/fcm/send -d '"registration_ids":["$FCMTOKEN"], "dry_run": true'【参考方案3】:

您可以通过调用来验证 FCM 令牌

(GET) https://iid.googleapis.com/iid/info/YOUR_APP_TOKEN_HERE
[Header] => 'Authorization: key=YOUR_KEY'

简单易行。

如果令牌有效,那么它将返回 200 状态代码以及 JSON 格式的更多详细信息,或者如果它无效,则状态代码将返回 400 以及 JSON 格式的错误详细信息。

【讨论】:

参考:developers.google.com/instance-id/reference/server 如果 YOUR_APP_TOKEN_HERE 是 FCM 令牌,从哪里检索 YOUR_KEY? @StefanZivkovic - 这是用户的 jwt 令牌【参考方案4】:

不存在这样的东西,您可以从令牌中获得的唯一信息是应用信息,而不是它是否有效

https://developers.google.com/instance-id/reference/server#get_information_about_app_instances

您应该做的是在发送推送时注意响应,如果密钥不再有效,响应将告诉您应该删除哪些密钥NotRegistered

https://firebase.google.com/docs/cloud-messaging/server

【讨论】:

当使用 instance-id 端点时,您可以检查令牌的信息,并且响应将指示(不是具体地)令牌无效,因为没有令牌信息或如果令牌格式无效。【参考方案5】:

在发送下游消息之前,无法验证令牌是否仍然有效。您需要做的是在发送消息后检查响应,然后检查响应是否包含任何错误。

例如,如果服务器返回一个200 + error:NotRegistered http 代码,则意味着现有的注册令牌可能不再有效。

在“Downstream message error response codes of FGC”部分,您会发现记录了所有可能的状态响应。

【讨论】:

以上是关于Firebase 云消息传递 - 如何验证令牌?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 中删除 Firebase 云消息传递令牌

如何将 FireBase 云消息传递令牌存储在 Android 的 firebase 数据库中?

用户注销 React Native 应用程序时如何删除 Firebase 云消息传递令牌?

如何在不请求通知权限的情况下获取 Firebase 云消息传递的注册令牌?

在 ViewModel SwiftUI 类中存储 Firebase 云消息传递令牌

Firebase 云消息传递令牌和服务器密钥有啥区别?