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

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

過時的註冊權杖

過期註冊權杖是指與閒置裝置 (且 超過一個月未連線至 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)
    }

每次擷取權杖時,系統都會透過呼叫 sendTokenToServer 將權杖儲存在 Cloud Firestore 中:

    /**
     * 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()
        }
    });

只有在符記在 270 天後過期,或是用戶端明確取消註冊時,FCM 才會傳回無效的符記回應。如果您需要根據自己的定義,更準確地追蹤過時性,可以主動移除過時的註冊權杖

定期更新權杖

建議您定期擷取並更新所有註冊權杖 。您必須:

  • 在用戶端應用程式中新增應用程式邏輯,以使用 適當的 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 SDKFCM 後端刪除權杖與主題的對應。

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

評估提交成效

如要取得最準確的訊息傳送情況,請盡量只將訊息傳送至目前使用的應用程式執行個體。如果您經常向訂閱人數眾多的主題傳送訊息,這項功能就特別重要。如果部分訂閱者實際上處於閒置狀態,這可能會對您的放送統計資料造成重大影響。

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

  • 使用 Google Analytics、BigQuery 擷取的資料或其他追蹤信號 是否表示權杖有效?
  • 先前的放送嘗試是否在一段時間後持續失敗?
  • 過去一個月內,您是否在伺服器上更新註冊權杖?
  • 針對 Android 裝置,FCM Data API 是否會回報因 droppedDeviceInactive 導致訊息傳送失敗的百分比偏高?

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