หากใช้ API ของ FCM เพื่อสร้างคำขอส่งแบบเป็นโปรแกรม คุณจะทำสิ่งต่อไปนี้ได้ พบว่าเมื่อเวลาผ่านไป คุณจะใช้ทรัพยากรโดยสูญเปล่าโดยการส่งข้อความไปที่ อุปกรณ์ซึ่งมีโทเค็นการลงทะเบียนที่ไม่อัปเดต สถานการณ์นี้อาจส่งผลต่อข้อความ ข้อมูลการแสดงโฆษณาที่รายงานในคอนโซล Firebase หรือข้อมูลที่ส่งออกไปยัง BigQuery แสดงการลดลงอย่างมาก (แต่ไม่ถูกต้องจริงๆ) คู่มือนี้กล่าวถึงมาตรการบางอย่างที่คุณทำได้เพื่อช่วยให้การกำหนดเป้าหมายข้อความมีประสิทธิภาพและการรายงานการนำส่งที่ถูกต้อง
โทเค็นการลงทะเบียนไม่มีอัปเดตและหมดอายุ
โทเค็นการลงทะเบียนที่ล้าสมัยคือโทเค็นที่เชื่อมโยงกับอุปกรณ์ที่ไม่ได้ใช้งานซึ่งไม่ได้เชื่อมต่อกับ FCM เป็นเวลานานกว่า 1 เดือน เมื่อเวลาผ่านไปก็จะน้อยลง และมีแนวโน้มน้อยลงที่อุปกรณ์จะเชื่อมต่อกับ FCM อีก ข้อความ การส่งและ Fanouts หัวข้อสำหรับโทเค็นที่ไม่มีอัปเดตเหล่านี้มักไม่เคยมีมาก่อน จัดส่งแล้ว
มีสาเหตุหลายประการที่ทำให้โทเค็นไม่มีอัปเดต ตัวอย่างเช่น อุปกรณ์ที่เชื่อมโยงกับโทเค็นอาจสูญหาย ถูกทำลาย หรือเก็บไว้แล้วลืม
เมื่อโทเค็นที่ไม่มีอัปเดตครบ 270 วัน FCM จะพิจารณาโทเค็นเหล่านั้น โทเค็นที่หมดอายุ เมื่อโทเค็นหมดอายุ FCM จะทําเครื่องหมายว่าไม่ถูกต้อง และ ปฏิเสธการส่งไปให้ อย่างไรก็ตาม FCM จะออกโทเค็นใหม่สําหรับอินสแตนซ์แอปในกรณีที่อุปกรณ์เชื่อมต่ออีกครั้งและเปิดแอป (ซึ่งเกิดขึ้นได้น้อยมาก)
แนวทางปฏิบัติแนะนำพื้นฐาน
มีแนวทางปฏิบัติพื้นฐานบางอย่างที่คุณควรทำตามในแอปที่ใช้ FCM API เพื่อสร้างคำขอส่งแบบเป็นโปรแกรม แนวทางปฏิบัติแนะนำหลักๆ มีดังนี้
- เรียกข้อมูลโทเค็นการลงทะเบียนจาก FCM และจัดเก็บไว้ในเซิร์ฟเวอร์ บทบาทสําคัญของเซิร์ฟเวอร์คือการติดตามโทเค็นของไคลเอ็นต์แต่ละรายและอัปเดตรายการโทเค็นที่ใช้งานอยู่ เราขอแนะนำ การใช้การประทับเวลาของโทเค็นในโค้ดและเซิร์ฟเวอร์ของคุณ และการอัปเดต การประทับเวลานี้ในช่วงเวลาที่สม่ำเสมอ
- รักษาความใหม่ของโทเค็นและนำโทเค็นเก่าออก นอกจาก การนำโทเค็นที่ FCM เห็นว่าใช้ไม่ได้อีกต่อไปออก คุณอาจต้อง เพื่อเฝ้าระวังสัญญาณอื่นๆ ที่บอกว่าโทเค็นกลายเป็นเก่าแล้ว และลบออก โดยไม่ต้องขอ คู่มือนี้จะกล่าวถึงตัวเลือกบางอย่างในการบรรลุเป้าหมายนี้
เรียกดูและจัดเก็บโทเค็นการลงทะเบียน
SDK ของ FCM จะสร้างการลงทะเบียนเมื่อเริ่มต้นแอปครั้งแรก สำหรับอินสแตนซ์ของแอปไคลเอ็นต์ โทเค็นนี้เป็นสิ่งที่คุณต้องใส่ในคำขอส่งที่มีการกําหนดเป้าหมายจาก API หรือเพิ่มในการติดตามหัวข้อเพื่อกําหนดเป้าหมายหัวข้อ
เราขอแนะนําอย่างยิ่งให้แอปของคุณดึงข้อมูลโทเค็นนี้เมื่อเริ่มต้นใช้งานครั้งแรกและบันทึกลงในเซิร์ฟเวอร์แอปพร้อมกับการประทับเวลา การประทับเวลานี้ต้องเป็น ติดตั้งโดยโค้ดและเซิร์ฟเวอร์ของคุณ เนื่องจากไม่ได้ให้โดย SDK FCM รายการ
นอกจากนี้ คุณยังต้องบันทึกโทเค็นลงในเซิร์ฟเวอร์และอัปเดตการประทับเวลาทุกครั้งที่มีการเปลี่ยนแปลง เช่น ในกรณีต่อไปนี้
- แอปได้รับการกู้คืนในอุปกรณ์เครื่องใหม่
- ผู้ใช้ถอนการติดตั้งแอปหรือติดตั้งแอปอีกครั้ง
- ผู้ใช้ล้างข้อมูลแอป
- แอปจะกลับมาใช้งานได้อีกครั้งหลังจากที่ 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
ไม่ว่าคุณจะใช้รูปแบบการกำหนดเวลาแบบใด อย่าลืมอัปเดตโทเค็นเป็นระยะๆ ความถี่ในการอัปเดตเดือนละครั้งจะสร้างสมดุลที่ดีระหว่างผลกระทบต่อแบตเตอรี่กับการตรวจหาโทเค็นการลงทะเบียนที่ไม่ได้ใช้งาน การรีเฟรชนี้ยังช่วยให้มั่นใจได้ว่าอุปกรณ์ที่ไม่มีการใช้งานจะรีเฟรชการลงทะเบียนเมื่อกลับมาใช้งานอีกครั้ง การรีเฟรชบ่อยกว่าสัปดาห์ละครั้งไม่มีประโยชน์
นำโทเค็นการลงทะเบียนที่ล้าสมัยออก
ก่อนที่จะส่งข้อความไปยังอุปกรณ์ โปรดตรวจสอบว่าการประทับเวลา
โทเค็นการลงทะเบียนอยู่ภายในระยะเวลาของกรอบเวลาที่ไม่มีการอัปเดต ตัวอย่างเช่น คุณสามารถ
สามารถใช้ 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 เดือน (หรือกรอบเวลาหมดอายุของคุณเอง) คุณควรยกเลิกการสมัครรับข้อมูลจากหัวข้อโดยใช้ Firebase Admin SDK เพื่อลบการแมปโทเค็นกับหัวข้อจากแบ็กเอนด์ FCM
ประโยชน์ของ 2 ขั้นตอนนี้คือ การ Fanouts จะเกิดขึ้นเร็วขึ้นตั้งแต่ จะมีโทเค็นเก่าให้กระจายออกน้อยลง และอินสแตนซ์ของแอปที่ไม่มีอัปเดตก็จะ สมัครใหม่โดยอัตโนมัติเมื่อมีการใช้งานอีกครั้ง
วัดความสําเร็จในการนำส่ง
หากต้องการเห็นภาพการส่งข้อความที่แม่นยำที่สุด คุณควรส่งข้อความไปยังอินสแตนซ์แอปที่ใช้อยู่เท่านั้น ซึ่งสำคัญมากหากคุณ ส่งข้อความถึงหัวข้อที่มีสมาชิกจำนวนมากเป็นประจำ หาก ของผู้ติดตามเหล่านั้นบางส่วนไม่ได้ใช้งาน ผลกระทบที่มีต่อการแสดงโฆษณาของคุณ อาจมีนัยสำคัญอย่างยิ่งเมื่อเวลาผ่านไป
ก่อนกําหนดเป้าหมายข้อความไปยังโทเค็น ให้พิจารณาสิ่งต่อไปนี้
- Google Analytics, ข้อมูลที่บันทึกไว้ใน BigQuery หรือสัญญาณการติดตามอื่นๆ บ่งชี้ว่าโทเค็นทำงานอยู่หรือไม่
- การส่งคำสั่งซื้อก่อนหน้านี้ล้มเหลวอย่างต่อเนื่องเป็นระยะเวลาหนึ่งหรือไม่
- โทเค็นการลงทะเบียนได้รับการอัปเดตในเซิร์ฟเวอร์ของคุณในเดือนที่ผ่านมาหรือไม่
- สำหรับอุปกรณ์ Android ให้ใช้ FCM Data API
รายงานว่าพบความผิดพลาดในการส่งข้อความเนื่องจาก
droppedDeviceInactive
ใช่ไหม
ดูข้อมูลเพิ่มเติมเกี่ยวกับการนำส่งได้ที่ การทำความเข้าใจการส่งข้อความ