แนวทางปฏิบัติแนะนำสำหรับการจัดการโทเค็นการลงทะเบียน FCM

หากคุณใช้ FCM API เพื่อสร้างคำขอส่งแบบเป็นโปรแกรม คุณจะทำสิ่งต่อไปนี้ได้ พบว่าเมื่อเวลาผ่านไป คุณจะใช้ทรัพยากรโดยสูญเปล่าโดยการส่งข้อความไปที่ อุปกรณ์ซึ่งมีโทเค็นการลงทะเบียนที่ไม่อัปเดต สถานการณ์นี้อาจส่งผลต่อข้อความ ข้อมูลการแสดงโฆษณาที่รายงานในคอนโซล Firebase หรือข้อมูลที่ส่งออกไปยัง BigQuery แสดงการลดลงอย่างมาก (แต่ไม่ถูกต้องจริงๆ) ช่วงเวลานี้ ไกด์จะพูดถึงมาตรการบางอย่างที่คุณสามารถใช้เพื่อให้ข้อความมีประสิทธิภาพ การกำหนดเป้าหมายและการรายงานการแสดงโฆษณาที่ถูกต้อง

โทเค็นการลงทะเบียนไม่มีอัปเดตและหมดอายุ

โทเค็นการลงทะเบียนที่ไม่มีการอัปเดตคือโทเค็นที่เชื่อมโยงกับอุปกรณ์ที่ไม่ได้ใช้งาน ไม่ได้เชื่อมต่อกับ FCM นานกว่า 1 เดือน เมื่อเวลาผ่านไปก็จะน้อยลง และมีแนวโน้มน้อยลงที่อุปกรณ์จะเชื่อมต่อกับ FCM อีก ข้อความ การส่งและ Fanouts หัวข้อสำหรับโทเค็นที่ไม่มีอัปเดตเหล่านี้มักไม่เคยมีมาก่อน จัดส่งแล้ว

มีสาเหตุหลายประการที่ทำให้โทเค็นไม่มีอัปเดต ตัวอย่างเช่น อุปกรณ์ โทเค็นที่เชื่อมโยงด้วยอาจสูญหาย ถูกทำลาย หรือถูกเก็บไว้ในพื้นที่เก็บข้อมูล และ ลืม

FCM จะพิจารณาโทเค็นที่ไม่มีการอัปเดตเมื่อไม่มีการใช้งานเป็นเวลา 270 วัน โทเค็นที่หมดอายุ เมื่อโทเค็นหมดอายุ FCM จะทําเครื่องหมายว่าไม่ถูกต้อง และ ปฏิเสธการส่งไปให้ อย่างไรก็ตาม FCM จะออกโทเค็นใหม่สำหรับแอป ในบางกรณีที่เกิดขึ้นไม่บ่อยนัก อุปกรณ์เชื่อมต่ออีกครั้งและเปิดแอปไว้

แนวทางปฏิบัติแนะนำเบื้องต้น

มีแนวทางปฏิบัติพื้นฐานบางอย่างที่คุณควรปฏิบัติตามในแอปที่ใช้ FCM API สำหรับสร้างคำขอส่งแบบเป็นโปรแกรม เกมหลักที่ดีที่สุด ดังนี้

  • เรียกข้อมูลโทเค็นการลงทะเบียนจาก FCM และจัดเก็บไว้ใน เซิร์ฟเวอร์ บทบาทสำคัญสำหรับเซิร์ฟเวอร์คือการติดตามข้อมูล โทเค็นและเก็บรายการโทเค็นที่ใช้งานอยู่ที่อัปเดต เราขอแนะนำ การใช้การประทับเวลาของโทเค็นในโค้ดและเซิร์ฟเวอร์ของคุณ และการอัปเดต การประทับเวลานี้ในช่วงเวลาที่สม่ำเสมอ
  • รักษาความใหม่ของโทเค็นและนำโทเค็นเก่าออก นอกจาก การนำโทเค็นที่ FCM เห็นว่าไม่ถูกต้องออก คุณอาจต้องการ เพื่อเฝ้าระวังสัญญาณอื่นๆ ที่บอกว่าโทเค็นกลายเป็นเก่าแล้ว และลบออก โดยไม่ต้องขอ คู่มือนี้จะกล่าวถึงตัวเลือกบางอย่างในการบรรลุเป้าหมายนี้

เรียกข้อมูลและจัดเก็บโทเค็นการลงทะเบียน

FCM SDK จะสร้างการลงทะเบียนเมื่อเริ่มต้นแอปของคุณเป็นครั้งแรก สำหรับอินสแตนซ์ของแอปไคลเอ็นต์ คุณต้องรวมไว้ในโทเค็นนี้ คำขอส่งที่กำหนดเป้าหมายจาก API หรือเพิ่มการสมัครรับข้อมูลตามหัวข้อเพื่อการกำหนดเป้าหมาย หัวข้อ

เราขอแนะนําอย่างยิ่งให้แอปของคุณเรียกโทเค็นนี้เมื่อเริ่มต้นระบบครั้งแรก แล้วบันทึก ไปยังเซิร์ฟเวอร์แอปพร้อมกับการประทับเวลา การประทับเวลานี้ต้องเป็น ติดตั้งโดยโค้ดและเซิร์ฟเวอร์ของคุณ เนื่องจากไม่ได้ให้โดย FCM SDK

นอกจากนี้ คุณยังควรบันทึกโทเค็นไว้ในเซิร์ฟเวอร์และอัปเดตการประทับเวลา เมื่อใดก็ตามที่มีการเปลี่ยนแปลง เช่น

  • แอปได้รับการกู้คืนในอุปกรณ์เครื่องใหม่
  • ผู้ใช้ถอนการติดตั้งแอปหรือติดตั้งแอปอีกครั้ง
  • ผู้ใช้ล้างข้อมูลแอป
  • แอปจะกลับมาใช้งานได้อีกครั้งหลังจากที่ FCM ได้หมดอายุแล้ว โทเค็น

ตัวอย่าง: จัดเก็บโทเค็นและการประทับเวลาใน Cloud Firestore

ตัวอย่างเช่น คุณใช้ Cloud Firestore เพื่อจัดเก็บโทเค็นในคอลเล็กชันได้ ที่ชื่อ fcmTokens รหัสเอกสารแต่ละรหัสในคอลเล็กชันสอดคล้องกับ รหัสผู้ใช้ และเอกสารจะจัดเก็บโทเค็นการลงทะเบียนปัจจุบัน การประทับเวลาที่อัปเดตล่าสุด ใช้ฟังก์ชัน 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 จะถือว่าโทเค็นไม่มีอัปเดต หากแอปของตน ไม่ได้เชื่อมต่ออินสแตนซ์มา 1 เดือนแล้ว โทเค็นที่เก่ากว่า 1 เดือนมีแนวโน้ม เป็นอุปกรณ์ที่ไม่ได้ใช้งาน อุปกรณ์ที่ใช้งานอยู่ อาจจะต้องรีเฟรช โทเค็น

เวลา 1 เดือนอาจสั้นหรือยาวเกินไป ขึ้นอยู่กับกรณีการใช้งานของคุณ เพื่อกำหนดเกณฑ์ที่เหมาะกับคุณ

ตรวจหาการตอบกลับโทเค็นที่ไม่ถูกต้องจากแบ็กเอนด์ 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) จากนั้นส่งโทเค็นปัจจุบันไปยังเซิร์ฟเวอร์ของแอปเพื่อจัดเก็บข้อมูล (พร้อมการประทับเวลา) ซึ่งอาจเป็นงานรายเดือนที่กำหนดค่าไว้ให้ครอบคลุมทั้งหมด ไคลเอ็นต์หรือโทเค็น
  • เพิ่มตรรกะเซิร์ฟเวอร์เพื่ออัปเดตการประทับเวลาของโทเค็นในช่วงเวลาที่สม่ำเสมอ ไม่ว่าโทเค็นจะมีการเปลี่ยนแปลงหรือไม่ก็ตาม

ตัวอย่างตรรกะ Android สำหรับการอัปเดตโทเค็นโดยใช้ WorkManager ดู การจัดการโทเค็น Cloud Messaging ในบล็อก Firebase

ไม่ว่าคุณจะใช้รูปแบบการกำหนดเวลาแบบใด อย่าลืมอัปเดตโทเค็นเป็นระยะๆ CANNOT TRANSLATE ความถี่ในการอัปเดตเดือนละครั้งเพื่อสร้างสมดุลระหว่างผลกระทบของแบตเตอรี่ และตรวจหาโทเค็นการลงทะเบียนที่ไม่ได้ใช้งาน เมื่อคุณทำการรีเฟรชนี้ คุณยัง ตรวจสอบให้แน่ใจว่าอุปกรณ์ใดๆ ที่ไม่มีการใช้งานจะรีเฟรชการลงทะเบียน กลับมาใช้งานได้ ไม่มีประโยชน์ที่จะทำการปรับปรุงให้บ่อยขึ้น รายสัปดาห์

นำโทเค็นการจดทะเบียนที่ไม่มีการอัปเดตออก

ก่อนที่จะส่งข้อความไปยังอุปกรณ์ โปรดตรวจสอบว่าการประทับเวลา โทเค็นการลงทะเบียนอยู่ภายในระยะเวลาของกรอบเวลาที่ไม่มีการอัปเดต ตัวอย่างเช่น คุณสามารถ สามารถใช้ 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(); });
});

ยกเลิกการสมัครโทเค็นที่ไม่มีอัปเดตจากหัวข้อ

หากคุณใช้หัวข้อ คุณอาจต้องยกเลิกการลงทะเบียนโทเค็นที่ไม่มีการอัปเดตจากหัวข้อด้วย ที่ได้สมัครสมาชิกไว้ ซึ่งแบ่งออกเป็น 2 ขั้นตอน ดังนี้

  1. แอปของคุณควรสมัครรับหัวข้อต่างๆ อีกครั้งเดือนละครั้ง และเมื่อใดก็ตามที่ การเปลี่ยนแปลงโทเค็นการลงทะเบียน ซึ่งจะเป็นวิธีการเยียวยาตนเองที่ การสมัครใช้บริการจะปรากฏขึ้นอีกครั้งโดยอัตโนมัติเมื่อแอปกลับมาใช้งานได้อีกครั้ง
  2. หากอินสแตนซ์ของแอปไม่มีการใช้งานเป็นเวลา 1 เดือน (หรือกรอบเวลาที่ไม่มีการอัปเดตของคุณเอง) ควรยกเลิกการสมัครรับข้อมูลจากหัวข้อโดยใช้ Firebase Admin SDK เพื่อ ลบโทเค็นกับการแมปหัวข้อจากแบ็กเอนด์ FCM

ประโยชน์ของ 2 ขั้นตอนนี้คือ การ Fanouts จะเกิดขึ้นเร็วขึ้นตั้งแต่ จะมีโทเค็นเก่าให้กระจายออกน้อยลง และอินสแตนซ์ของแอปที่ไม่มีอัปเดตก็จะ สมัครใหม่โดยอัตโนมัติเมื่อมีการใช้งานอีกครั้ง

วัดความสำเร็จในการแสดงโฆษณา

เพื่อให้ได้ภาพของการส่งข้อความที่แม่นยำที่สุด คุณควรส่งเฉพาะ ไปยังอินสแตนซ์แอปที่ใช้อยู่ ซึ่งสำคัญมากหากคุณ ส่งข้อความถึงหัวข้อที่มีสมาชิกจำนวนมากเป็นประจำ หาก ของผู้ติดตามเหล่านั้นบางส่วนไม่ได้ใช้งาน ผลกระทบที่มีต่อการแสดงโฆษณาของคุณ อาจมีนัยสำคัญอย่างยิ่งเมื่อเวลาผ่านไป

ก่อนที่จะกำหนดเป้าหมายข้อความไปยังโทเค็น โปรดพิจารณาสิ่งต่อไปนี้

  • Google Analytics, ข้อมูลที่บันทึกไว้ใน BigQuery หรือสัญญาณการติดตามอื่นๆ ว่าโทเค็นมีการใช้งานอยู่หรือไม่
  • เคยพยายามนำส่งก่อนหน้านี้ไม่สำเร็จอย่างต่อเนื่องในช่วงระยะเวลาหนึ่งหรือไม่
  • โทเค็นการลงทะเบียนได้รับการอัปเดตในเซิร์ฟเวอร์ของคุณในเดือนที่ผ่านมาหรือไม่
  • สำหรับอุปกรณ์ Android ให้ใช้ FCM Data API รายงานว่าพบความผิดพลาดในการส่งข้อความเนื่องจาก droppedDeviceInactive ใช่ไหม

ดูข้อมูลเพิ่มเติมเกี่ยวกับการนำส่งได้ที่ การทำความเข้าใจการส่งข้อความ