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

问题描述 投票:0回答:7

我正在使用 Firebase Cloud Messaging (FCM),并且每次在客户设备上生成新令牌时,都会根据下面的缩写代码...我将此新令牌发送到我的服务器数据库(云),并将其保存在其中能够使用 CFM API 将未来的推送通知从服务器发送到设备。

    //public class CFMInstanceIDService extends FirebaseInstanceIdService ...

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

通过执行此操作,我在服务器上拥有客户登录的所有(多个)设备的列表。 (平板电脑、手机、iPhone、Android 等)

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

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

android firebase firebase-cloud-messaging
7个回答
49
投票

这是一个示例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 支持团队得到了这个答案。


26
投票

其实有一个解决方法,你可以使用

dry_run = true

此参数设置为 true 时,允许开发人员测试请求而无需实际发送消息。

firebase 文档

如果用户取消订阅,您会收到

NotRegistered
的回复,但不会执行真正的发送


20
投票

您可以通过调用

来验证 FCM 令牌
(GET) https://iid.googleapis.com/iid/info/YOUR_APP_TOKEN_HERE
[Header] => 'Authorization: key=YOUR_KEY'

简单又容易。

如果令牌有效,则它将返回 200 状态代码,并包含 JSON 格式的更多详细信息;如果令牌无效,则状态代码将为 400,并包含 JSON 格式的错误详细信息。


9
投票

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

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

您应该做的是当您发送推送时观察响应,如果密钥不再有效,响应会告诉您应该删除哪些密钥

NotRegistered

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


2
投票

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

例如,如果服务器返回

200 + error:NotRegistered
http 代码,则意味着现有的注册令牌可能不再有效。

在“FGC 的下游消息错误响应代码”部分中,您将找到记录的每个可能的状态响应。


0
投票

如果您有 adminsdk crendeital,您可以使用此代码:

func TestPushToken(t *testing.T) {
    ctx := context.Background()

    opt := option.WithCredentialsJSON([]byte(credential))
    app, err := firebase.NewApp(ctx, nil, opt)
    if err != nil {
        t.Error(err)
    }

    msg := &messaging.Message{
        Notification: &messaging.Notification{
            Title: "Hi",
            Body:  fmt.Sprintf("Welcome at %d", time.Now().Unix()),
        },
        Token: pushToken,
    }

    fcmClient, err := app.Messaging(ctx)
    run, err := fcmClient.SendDryRun(ctx, msg)
    if err != nil {
        t.Error(err)
    }
    fmt.Println(run)
}

如果出现任何错误,则说明pushToken无效。或者你会得到类似的回应

/messages/fake_message_id

0
投票

在新的 HTTP v1 API 中,dry_run 标志(在其他答案中描述)现在称为 validate_only:

validate_only
用于测试请求而不实际传递消息的标志。

© www.soinside.com 2019 - 2024. All rights reserved.