【问题标题】:How to handle Firebase Cloud Messaging onTokenRefresh on the back end如何在后端处理 Firebase 云消息传递 onTokenRefresh
【发布时间】:2018-04-23 08:51:04
【问题描述】:

我们有一个使用 Firebase 云消息传递来驱动应用内聊天功能的跨平台应用。一些用户可能会在不止一台设备上主动使用该应用程序。因此,只要用户的设备收到onTokenRefresh 触发器,我们就会将该新注册令牌发送到服务器以针对用户进行保存。现在假设用户已经在服务器数据库中存储了一些注册令牌,我们如何知道这些令牌是否用于同一设备并且现在应该被删除,或者它们是否用于不同的设备并且我们应该继续向所有设备发送?

我已阅读 docs on Device Group Messaging,但它看起来对我们的应用程序来说开销太大,而且 Firebase 服务器似乎不会自动为您从组中删除被取代的注册令牌。

如果我们简单地假设记录的所有用户注册令牌都处于活动状态并发送给所有人,我们是否可以使用响应来决定是否需要修剪服务器上的令牌?

{
    "multicast_id": 6538766984100364080,
    "success": 1,
    "failure": 0,
    "canonical_ids": 0,
    "results": [
        {
            "message_id": "0:1510294979553090%029da28f029da28f"
        }
    ]
}

根据this answer 和一些针对带有替换令牌的HTTP API 的测试,看起来"success":1 结果不是不应该删除令牌的可靠指标,因为替换的令牌往往会继续存在。此外,"success": 0 结果可能不是我们可以删除令牌的可靠指标,因为它可能只是表明有效、活动令牌上的临时网络错误。

API documentation 讨论了如何解释结果中的可选registration_id,但目前尚不清楚这与NotRegistered 错误有何不同以及采取什么最佳措施。

任何关于如何处理和管理 FCM 设备令牌到达服务器的见解或最佳实践将不胜感激。

【问题讨论】:

    标签: push-notification firebase-cloud-messaging


    【解决方案1】:

    我也遇到了确切的挑战,不得不下定决心找到一个解决方案: 根据设备 ID 为用户存储每个令牌。 有趣的是,这个函数实际上存在于 firebase 消息传递方法中。但更令人惊讶的是,没有文档可以处理这种情况。 https://firebase.google.com/docs/reference/android/com/google/firebase/iid/FirebaseInstanceId.html#getId()

    因此,总而言之,在向服务器发送新令牌的同时,还要发送 getId() 方法返回的设备 ID,并使用它来强制每个设备令牌的唯一性。

    问题解决了:D

    【讨论】:

    • 文档说“唯一标识应用程序实例的标识符”,这意味着每次在具有相同设备 ID 的同一设备上新启动应用程序时,它都会更新。这只能帮助识别在同一应用会话(实例)中被替换的设备 ID,而这些设备 ID 通常不会在它们被替换时被替换。
    【解决方案2】:

    我们将采用假设所有onTokenRefresh id 都是新的、我们添加到服务器设备列表中的附加设备的方法。然后,每当我们发送消息时,我们都会使用返回的结果来删除或替换已弃用的设备令牌。用 PHP 实现:

    // $devices is a list of the device ids to send to
    
    // 1. send a message to a list of devices
    $response = Firebase::request('POST', 'send', ['json' => $this->payloadFor($devices)]);
    
    // 2. check the response to see if we need to make changes to the device list
    
    // if it is a network error, no changes needed
    if ($response->getStatusCode() != 200) {
        Log::info("FCM http error " . $response->getStatusCode());
        return;
    }
    
    $body = json_decode($response->getBody(), $asArray = true);
    
    // do we need to dig deeper?
    if ($body['failure'] == 0 && $body['canonical_ids'] == 0) return;
    
    if (count($body['results']) != count($devices)) {
        Log::info("FCM error : device count not matching result count");
        return;
    }
    
    // we have errors that need processing, so step through the results list
    foreach ($body['results'] as $key => $result) {
    
        if (isset($result['error'])) {
            switch ($result['error']) {
                case 'NotRegistered':
                case 'InvalidRegistration':
                    $deletedRows = Device::where('token', $devices[$key])->delete();
                    Log::info("FCM trimmed: $devices[$key]");
                    break;
    
                default:
                    Log::info("FCM error " . $result['error']);
                    break;
            }
        }
    
        // we need to update some device tokens
        if (isset($result['registration_id'])) {
            Device::deprecate($devices[$key], $result['registration_id']);
            Log::info("FCM replaced: " . $devices[$key]);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-08-28
      • 1970-01-01
      • 1970-01-01
      • 2021-02-07
      • 1970-01-01
      • 1970-01-01
      • 2020-05-15
      • 1970-01-01
      • 2021-12-02
      相关资源
      最近更新 更多