管理 FCM 註冊權杖的最佳做法

如果您使用 FCM API 透過程式輔助方式建構傳送要求,您可以 隨著時間的推移,您一直無法收到發送訊息,從而浪費資源。 註冊權杖已經過期的裝置。在這種情況下,訊息可能會受到影響 Firebase 控制台回報的交付資料,或匯出至 BigQuery 的資料 似乎大幅 (但實際上) 大幅下降。這個 本指南將說明哪些方法有助於確保訊息達到良好成效 以及有效的放送報表

註冊權杖已過時和過期

過期註冊權杖是指與閒置裝置 (且 超過 1 個月未連線到 FCM。隨著時間的推移, 也比較不會讓裝置再次連線到 FCM。訊息 傳送和主題排擠給這些過時的代幣 廣告放送。

權杖過時有幾種原因,例如: 與相關權杖相關聯的權杖可能會遺失、刪除或放入儲存空間 忘記。

如果過時權杖閒置達 270 天,FCM 會將這些權杖納入考量 過期的符記。權杖到期後,FCM 會將其標示為無效, 就會拒絕接收郵件不過,FCM 會為應用程式核發新的權杖 是在極罕見的情況下,裝置必須重新連線並開啟應用程式。

基本最佳做法

在使用任何應用程式 FCM API,透過程式建構傳送要求。最棒的 做法如下:

  • 從 FCM 擷取註冊權杖並儲存在 伺服器。伺服器的重要角色是追蹤每個用戶端的 並保留更新後的有效權杖清單強烈建議你 在程式碼和伺服器中導入權杖時間戳記,然後進行更新 這個時間戳記每隔 15 天
  • 維持權杖更新間隔,並移除過時的權杖。除了 移除 FCM 不再有效的權杖 監控其他符記過時並將它們移除 主動出擊。本指南將說明達成此目標的一些方法。

擷取及儲存註冊權杖

應用程式首次啟動時,FCM SDK 會產生註冊資料 符記。也就是您必須加入的憑證 指定的 API 傳送請求,或加進主題訂閱來指定目標 主題。

強烈建議您讓應用程式在初始啟動時擷取這個權杖並儲存 連同時間戳記一起發布至應用程式伺服器。這個時間戳記必須是 無法使用程式碼和伺服器實作程式碼, FCM SDK。

另外,請務必將權杖儲存至伺服器並更新時間戳記 例如時間:

  • 應用程式會在新裝置上還原
  • 使用者解除安裝或重新安裝應用程式
  • 使用者清除應用程式資料
  • 應用程式會在 FCM 到期後再次生效 權杖

範例:在 Cloud Firestore 中儲存符記和時間戳記

例如,您可以使用 Cloud Firestore 將符記儲存在集合中 名為 fcmTokens。集合內的每個文件 ID 都會對應至 使用者 ID,而文件會儲存目前的註冊符記及其 上次更新的時間戳記。使用 set 函式,如以下 Kotlin 範例所示:

    /**
     * Persist token to third-party servers.
     *
     * Modify this method to associate the user's FCM registration token with any server-side account
     * maintained by your application.
     *
     * @param token The new token.
     */
    private fun sendTokenToServer(token: String?) {
        // If you're running your own server, call API to send token and today's date for the user

        // Example shown below with Firestore
        // Add token and timestamp to Firestore for this user
        val deviceToken = hashMapOf(
            "token" to token,
            "timestamp" to FieldValue.serverTimestamp(),
        )
        // Get user ID from Firebase Auth or your own server
        Firebase.firestore.collection("fcmTokens").document("myuserid")
            .set(deviceToken)
    }

每當擷取到權杖時,系統就會透過呼叫的方式,將權杖儲存在 Cloud Firestore 中 sendTokenToServer:

    /**
     * Called if the FCM registration token is updated. This may occur if the security of
     * the previous token had been compromised. Note that this is called when the
     * FCM registration token is initially generated so this is where you would retrieve the token.
     */
    override fun onNewToken(token: String) {
        Log.d(TAG, "Refreshed token: $token")

        // If you want to send messages to this application instance or
        // manage this apps subscriptions on the server side, send the
        // FCM registration token to your app server.
        sendTokenToServer(token)
    }
        var token = Firebase.messaging.token.await()

        // Check whether the retrieved token matches the one on your server for this user's device
        val preferences = this.getPreferences(Context.MODE_PRIVATE)
        val tokenStored = preferences.getString("deviceToken", "")
        lifecycleScope.launch {
            if (tokenStored == "" || tokenStored != token)
            {
                // If you have your own server, call API to send the above token and Date() for this user's device

                // Example shown below with Firestore
                // Add token and timestamp to Firestore for this user
                val deviceToken = hashMapOf(
                    "token" to token,
                    "timestamp" to FieldValue.serverTimestamp(),
                )

                // Get user ID from Firebase Auth or your own server
                Firebase.firestore.collection("fcmTokens").document("myuserid")
                    .set(deviceToken).await()
            }
        }

維持權杖更新間隔,並移除過時的權杖

判斷符記是最新還是過時並不容易。目的地: 涵蓋所有情況,建議您在思考符記時設定門檻 過時。根據預設,如果權杖已過時,FCM 會將權杖視為已過時 執行個體已有一個月未連線。任何超過一個月的權杖都可能 並非閒置裝置;使用中的裝置將會重新整理 產生下一個符記

一個月的時間可能會太長或太久,視實際情況而定,並會 找出適合你的條件

偵測來自 FCM 後端的無效權杖回應

請務必偵測 FCM 發出的無效權杖回應,並在以下日期前回覆: 從系統中刪除任何已知無效的註冊權杖 或已過期。使用 HTTP v1 API 時,這些錯誤訊息可能表示 您的傳送要求指定的無效或過期的權杖:

  • UNREGISTERED (HTTP 404)
  • INVALID_ARGUMENT (HTTP 400)

如果您確定訊息酬載有效,且收到 針對目標權杖的回應,您可以放心刪除 權杖,因為這個權杖會永遠失效。例如刪除無效權杖 您可以透過 Cloud Firestore,部署及執行函式,如下所示:

    // Registration token comes from the client FCM SDKs
    const registrationToken = 'YOUR_REGISTRATION_TOKEN';

    const message = {
    data: {
        // Information you want to send inside of notification
    },
    token: registrationToken
    };

    // Send message to device with provided registration token
    getMessaging().send(message)
    .then((response) => {
        // Response is a message ID string.
    })
    .catch((error) => {
        // Delete token for user if error code is UNREGISTERED or INVALID_ARGUMENT.
        if (errorCode == "messaging/registration-token-not-registered") {
            // If you're running your own server, call API to delete the
            token for the user

            // Example shown below with Firestore
            // Get user ID from Firebase Auth or your own server
            Firebase.firestore.collection("fcmTokens").document(user.uid).delete()
        }
    });

權杖過期時,FCM 只會傳回無效的權杖回應 270 天後,或是客戶明確取消註冊。如果您需要 根據自己的定義精確地追蹤過時情形 主動移除過期的註冊權杖

定期更新權杖

建議您定期擷取並更新所有註冊權杖 。為此,您必須執行下列操作:

  • 在用戶端應用程式中新增應用程式邏輯,以使用 適當的 API 呼叫 (例如 token(completion):敬上 適用於 Apple 平台 getToken() ,然後將目前的權杖傳送至應用程式伺服器以便儲存 (並加上時間戳記)。這可以設為涵蓋所有流量的每月工作 用戶端或權杖
  • 新增伺服器邏輯,以定期更新權杖的時間戳記。 無論符記是否已變更

如需使用以下程式碼更新符記的 Android 邏輯範例: WorkManager、 看 管理雲端通訊權杖

無論您採用的時間模式為何,請務必定期更新權杖。一個 每月更新一次的頻率,在電池影響之間取得良好平衡 與偵測無效的註冊權杖執行這項重新整理作業後 確保處於閒置狀態的所有裝置會在無法使用時重新整理註冊資訊 就會再次生效提高更新頻率沒有任何好處 比每週多

移除過期的註冊權杖

傳送訊息至裝置前,請確定裝置的時間戳記 註冊權杖會在過時期限內。舉例來說, 導入 Cloud Functions for Firebase 來執行每日檢查 時間戳記是在已定義的過時期限內 (例如 const EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 30;),然後移除過時的權杖:

exports.pruneTokens = functions.pubsub.schedule('every 24 hours').onRun(async (context) => {
  // Get all documents where the timestamp exceeds is not within the past month
  const staleTokensResult = await admin.firestore().collection('fcmTokens')
      .where("timestamp", "<", Date.now() - EXPIRATION_TIME)
      .get();
  // Delete devices with stale tokens
  staleTokensResult.forEach(function(doc) { doc.ref.delete(); });
});

取消訂閱主題過時的權杖

如果您使用的是主題,建議您一併取消註冊主題中過時的權杖 訂閱的頻道這項程序包含兩個步驟:

  1. 您的應用程式每個月應重新訂閱一次主題,且 變更註冊權杖這會形成自我修復的解決方案 當應用程式再次進入使用中狀態時,訂閱項目就會自動重新顯示。
  2. 如果應用程式執行個體閒置了一個月 (或您自己的過時期限) 是否應使用 Firebase Admin SDK 從 FCM 後端刪除權杖與主題的對應關係。

這兩個步驟的好處是,隨著粉絲加入, 要擴散的過時權杖數量較少,而過時的應用程式執行個體 自動重新訂閱。

評估放送成效

為取得最準確的郵件傳送情況,建議您僅傳送 接收訊息,指出主動使用的應用程式執行個體。如果您 定期傳送訊息給擁有大量訂閱者的主題;如果 的訂閱者比例實際停用,並對提交內容的影響 長期下來,統計數據可能變得相當可觀

將訊息指定至權杖前,請先考慮:

  • 使用 Google Analytics、BigQuery 擷取的資料或其他追蹤信號 是否表示權杖有效?
  • 先前的放送嘗試是否在一段時間後持續失敗?
  • 伺服器中的註冊權杖在過去一個月內是否更新?
  • 如果是 Android 裝置,請務必改用 FCM Data API 指出郵件傳送失敗的比例偏高, 是droppedDeviceInactive嗎?

如要進一步瞭解提交資訊,請參閱 瞭解郵件傳送方式