หากคุณใช้ FCM API เพื่อสร้างคำขอส่งแบบเป็นโปรแกรม คุณอาจพบว่าเมื่อเวลาผ่านไป คุณกำลังเสียทรัพยากรไปกับการส่งข้อความไปยังอุปกรณ์ที่ไม่ได้ใช้งานซึ่งมีการลงทะเบียนที่ล้าสมัย สถานการณ์นี้อาจส่งผลต่อข้อมูลการส่งข้อความที่รายงานในคอนโซล Firebase หรือข้อมูลที่ส่งออกไปยัง BigQuery โดยแสดงเป็นอัตราการส่งที่ลดลงอย่างมาก (แต่ไม่ถูกต้องจริงๆ) คู่มือนี้จะกล่าวถึงมาตรการบางอย่างที่คุณสามารถทำได้เพื่อช่วยให้มั่นใจว่าการกำหนดเป้าหมายข้อความมีประสิทธิภาพและการรายงานการนำส่งถูกต้อง
การลงทะเบียนที่ไม่มีการอัปเดตและหมดอายุ
การลงทะเบียนที่ไม่มีการอัปเดตจะเชื่อมโยงกับอุปกรณ์ที่ไม่ได้ใช้งานซึ่งไม่ได้เชื่อมต่อกับ FCM นานกว่า 1 เดือน เมื่อเวลาผ่านไป โอกาสที่อุปกรณ์จะเชื่อมต่อกับ FCM อีกครั้งจะลดลงเรื่อยๆ การส่งข้อความและการกระจายหัวข้อสำหรับการลงทะเบียนที่ไม่มีการใช้งานเหล่านี้มีแนวโน้มที่จะไม่ได้รับการส่ง
การลงทะเบียนอาจไม่มีการอัปเดตเนื่องจากหลายสาเหตุ ตัวอย่างเช่น อุปกรณ์ที่เชื่อมโยงกับการลงทะเบียนอาจสูญหาย ถูกทำลาย หรือถูกเก็บไว้และถูกลืม
สำหรับ Android เมื่อไม่มีการใช้งานการลงทะเบียนเป็นเวลา 270 วัน FCM จะถือว่าการลงทะเบียนหมดอายุและจะรวบรวมขยะ เมื่อการลงทะเบียนหมดอายุ FCM จะทำเครื่องหมายว่าไม่ถูกต้องและปฏิเสธการส่งไปยังการลงทะเบียนนั้น โปรดทราบว่ารหัสการติดตั้ง Firebase (FID) จะได้รับการจัดการโดยบริการการติดตั้ง Firebase (FIS) ไม่ใช่ FCM ในกรณีที่เกิดขึ้นไม่บ่อยนักที่อุปกรณ์เชื่อมต่ออีกครั้งและแอปเปิดขึ้นหลังจากที่การลงทะเบียนถูกรวบรวมขยะแล้ว แอปไคลเอ็นต์จะลงทะเบียนกับ FCM อีกครั้งโดยใช้ FID ที่ดึงมาจาก FIS โปรดทราบว่า FID อาจมีการเปลี่ยนแปลง โปรดดูรายละเอียดเกี่ยวกับเวลาที่ออก FID ใหม่ที่หัวข้อจัดการการติดตั้ง Firebase
สำหรับแพลตฟอร์มอื่นๆ เช่น iOS นั้น FCM จะอาศัยบริการพุชที่สำคัญ (เช่น APN) ซึ่งไม่มีการหมดอายุตามการไม่มีการใช้งาน 270 วันเหมือนกัน เราขอแนะนำให้คุณรักษาความใหม่ของการลงทะเบียนและนำการลงทะเบียนที่ไม่มีการอัปเดตออกในเชิงรุก
แนวทางปฏิบัติแนะนำพื้นฐาน
มีแนวทางปฏิบัติพื้นฐานบางอย่างที่คุณควรปฏิบัติตามในแอปที่ใช้ API ของ FCM เพื่อสร้างคำขอส่งแบบเป็นโปรแกรม แนวทางปฏิบัติแนะนำหลักๆ มีดังนี้
- ดึงรหัสการติดตั้ง Firebase (FID) จาก FCM และจัดเก็บไว้ในเซิร์ฟเวอร์แอป บทบาทสำคัญของเซิร์ฟเวอร์คือการติดตาม FID ที่ลงทะเบียนของไคลเอ็นต์แต่ละรายและเก็บรายการ FID ที่ใช้งานอยู่ซึ่งอัปเดตแล้ว เราขอแนะนำอย่างยิ่งให้ใช้การประทับเวลาการลงทะเบียนในฐานข้อมูล และอัปเดตทุกครั้งที่มีการอัปโหลดการลงทะเบียน
- รักษาความใหม่ของการลงทะเบียนและนำการลงทะเบียนที่ไม่มีการใช้งานออก นอกเหนือจากการนำการลงทะเบียนที่ FCM ไม่ถือว่าถูกต้องอีกต่อไปออกแล้ว คุณอาจต้องตรวจสอบสัญญาณอื่นๆ ที่บ่งบอกว่าการลงทะเบียนไม่มีการอัปเดตและนำออกในเชิงรุก คู่มือนี้จะกล่าวถึงตัวเลือกบางอย่างในการดำเนินการดังกล่าว
ดึงข้อมูลและจัดเก็บรหัสการติดตั้ง Firebase
เมื่อเริ่มต้นแอปครั้งแรก SDK ของ FCM จะลงทะเบียนอินสแตนซ์แอปกับ FCM และแสดงรหัสการติดตั้ง Firebase (FID) นี่คือตัวระบุที่คุณต้องรวมไว้ในคำขอส่งที่กำหนดเป้าหมายจาก API หรือใช้สำหรับการสมัครรับข้อมูลหัวข้อ
เราขอแนะนำอย่างยิ่งให้บันทึก FID ไว้ในเซิร์ฟเวอร์แอปพร้อมกับการประทับเวลาเมื่อใดก็ตามที่มีการอัปโหลด การอัปเดตการประทับเวลาในคำขออัปโหลดทุกครั้งจะช่วยให้เซิร์ฟเวอร์ทราบว่าอินสแตนซ์แอปล่าสุดเปิดขึ้นเมื่อใด และซิงค์ข้อมูลกับแบ็กเอนด์ของ FCM สำเร็จหรือไม่
คุณควรจัดการการลงทะเบียนและการอัปเดตดังต่อไปนี้ ทั้งนี้ขึ้นอยู่กับว่าเปิดใช้หรือปิดใช้การเริ่มต้นอัตโนมัติ (รวมถึงไม่รองรับ)
- (แนะนำ) เมื่อเปิดใช้การเริ่มต้นอัตโนมัติ: SDK จะอัปเดตการลงทะเบียนให้เป็นปัจจุบันและตรวจสอบการเปลี่ยนแปลงโดยอัตโนมัติ ระบบจะเรียกใช้ Callback
onRegistered()เป็นประจำในการซิงค์ตามปกติระหว่างการเริ่มต้นแอป รวมถึงเมื่อมีการเปลี่ยนแปลง FID เพียงใช้ Callback นี้เพื่ออัปโหลด FID ไปยังเซิร์ฟเวอร์และบันทึกการประทับเวลาปัจจุบัน - เมื่อปิดใช้การเริ่มต้นอัตโนมัติ: ระบบจะไม่เรียกใช้ Callback
onRegistered()โดยอัตโนมัติเมื่อเริ่มต้น หากต้องการติดตามการลงทะเบียนและอัปเดตให้เป็นปัจจุบันอยู่เสมอ ให้เรียกใช้register()เมื่อเริ่มต้นแอป เช่น ใน Android ให้เรียกใช้ในonCreate()ของกิจกรรมหลัก การเรียกใช้ที่สำเร็จจะทริกเกอร์กระบวนการลงทะเบียน FCM โดยใช้ FID และส่งไปยัง CallbackonRegistered()ซึ่งจะช่วยให้แอปอัปโหลด FID และอัปเดตการประทับเวลาบนเซิร์ฟเวอร์ได้
ตัวอย่าง: จัดเก็บ FID และการประทับเวลาใน Cloud Firestore
เช่น คุณสามารถใช้ Cloud Firestore เพื่อจัดเก็บ FID ในคอลเล็กชันที่ชื่อว่า fcmRegistrations รหัสเอกสารแต่ละรายการในคอลเล็กชันจะสอดคล้องกับรหัสผู้ใช้ และเอกสารจะจัดเก็บ FID ปัจจุบันและการประทับเวลาที่อัปเดตล่าสุด ใช้ฟังก์ชัน set ดังที่แสดงในตัวอย่าง Kotlin นี้
private fun sendRegistrationToServer(installationId: String?) {
// If you're running your own server, call API to send registration details and today's date for the user
// Example shown uses Firestore
// Add FID and timestamp to Firestore for this user
val deviceFid = hashMapOf(
"installationId" to installationId,
"timestamp" to FieldValue.serverTimestamp(),
)
// Get user ID from Firebase Auth or your own server
Firebase.firestore.collection("fcmRegistrations").document("myuserid")
.set(deviceFid)
}
เมื่อใดก็ตามที่มีการลงทะเบียนหรืออัปเดตรหัสการติดตั้ง Firebase สำเร็จ ระบบจะเรียกใช้ Callback onRegistered() คุณควรใช้ Callback นี้เพื่ออัปโหลด FID และอัปเดตการประทับเวลา ดังนี้
override fun onRegistered(installationId: String) {
Log.d(TAG, "Registered installation ID: $installationId")
// Send the Firebase Installation ID (FID) to your app server. Your app
// server should save the FID and update the timestamp upon receipt.
sendRegistrationToServer(installationId)
}
ในกรณีที่ปิดใช้การเริ่มต้นอัตโนมัติ ให้เรียกใช้
register()
เมื่อเริ่มต้นแอป (เช่น ใน onCreate()) เพื่อทริกเกอร์ขั้นตอนการลงทะเบียนและการส่ง FID ผ่าน
onRegistered():
// Trigger manual registration if auto-initialization is turned off.
FirebaseMessaging.getInstance().register()
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
// The registration callback onRegistered() will be invoked with the current FID.
} else {
Log.w(TAG, "Failed to register with Firebase Cloud Messaging", task.exception)
}
}
รักษาความใหม่ของการลงทะเบียนและนำการลงทะเบียนที่ไม่มีการใช้งานออก
การพิจารณาว่าการลงทะเบียนเป็นข้อมูลใหม่หรือข้อมูลเก่าอาจไม่ใช่เรื่องง่ายเสมอไป คุณควรกำหนดเกณฑ์สำหรับกรณีที่พิจารณาว่าการลงทะเบียนไม่มีการใช้งานแล้วเพื่อให้ครอบคลุมทุกกรณี โดยค่าเริ่มต้น FCM จะถือว่าการลงทะเบียนไม่มีการใช้งานหากอินสแตนซ์ของแอปไม่ได้เชื่อมต่อเป็นเวลา 1 เดือน การลงทะเบียนที่เก่ากว่า 1 เดือนมีแนวโน้มที่จะเป็นอุปกรณ์ที่ไม่มีการใช้งาน เนื่องจากอุปกรณ์ที่ใช้งานอยู่จะรีเฟรชการลงทะเบียนของตนเอง
ทั้งนี้ขึ้นอยู่กับกรณีการใช้งานของคุณ ระยะเวลา 1 เดือนอาจสั้นหรือยาวเกินไป ดังนั้นคุณจึงเป็นผู้กำหนดเกณฑ์ที่เหมาะสมกับคุณ
ตรวจหาคำตอบที่เป็นโมฆะจากแบ็กเอนด์ FCM
โปรดตรวจสอบว่าได้ตรวจหาคำตอบที่เป็นโมฆะจาก FCM และตอบกลับโดยลบการลงทะเบียนที่ทราบว่าไม่ถูกต้องหรือหมดอายุออกจากระบบ เมื่อใช้ HTTP v1 API ข้อความแสดงข้อผิดพลาดเหล่านี้อาจบ่งชี้ว่าคำขอส่งของคุณกำหนดเป้าหมายเป็นการลงทะเบียนที่ไม่ถูกต้องหรือหมดอายุแล้ว
UNREGISTERED(HTTP 404)INVALID_ARGUMENT(HTTP 400)
หากคุณแน่ใจว่าเพย์โหลดข้อความถูกต้องและได้รับการตอบกลับอย่างใดอย่างหนึ่งต่อไปนี้สำหรับการลงทะเบียนที่กำหนดเป้าหมาย คุณสามารถลบบันทึกการลงทะเบียนนี้ได้อย่างปลอดภัย เนื่องจากจะใช้ไม่ได้อีกต่อไป ตัวอย่างเช่น หากต้องการลบการลงทะเบียนที่ไม่ถูกต้องออกจาก Cloud Firestore คุณสามารถติดตั้งใช้งานและเรียกใช้ฟังก์ชันดังต่อไปนี้
// Firebase Installation ID comes from the client FCM SDKs
const firebaseInstallationId = 'YOUR_FIREBASE_INSTALLATION_ID';
const message = {
data: {
// Information you want to send inside of notification
},
fid: firebaseInstallationId
};
// Send message to device with provided Firebase Installation ID
getMessaging().send(message)
.then((response) => {
// Response is a message ID string.
})
.catch((error) => {
// Delete registration for user if error code is UNREGISTERED or INVALID_ARGUMENT.
if (error.errorCode == "messaging/registration-token-not-registered") {
// If you're running your own server, call API to delete the registration for the user
// Example shown uses Firestore
// Get user ID from Firebase Auth or your own server
Firebase.firestore.collection("fcmRegistrations").document(user.uid).delete()
}
});
FCM จะแสดงผลคำตอบที่เป็นโมฆะหากการลงทะเบียนสำหรับอุปกรณ์ Android หมดอายุหลังจากไม่มีการใช้งานเป็นเวลา 270 วัน หรือหากไคลเอ็นต์ยกเลิกการลงทะเบียนอย่างชัดแจ้ง หากต้องการติดตามความล้าสมัยให้แม่นยำยิ่งขึ้นตามคำจำกัดความของคุณเอง คุณสามารถนำการลงทะเบียนที่ล้าสมัยออกในเชิงรุกได้
อัปเดตการลงทะเบียนเป็นประจำ
ไม่ว่าการลงทะเบียนจะอิงตาม FID หรือโทเค็นการลงทะเบียนเดิม เซิร์ฟเวอร์ของคุณควรอัปเดตการประทับเวลาการลงทะเบียนในฐานข้อมูลทุกครั้งที่มีคำขออัปโหลด การประทับเวลานี้ทำหน้าที่เป็นสัญญาณสำหรับการติดตั้งแอป ซึ่งช่วยให้ไคลเอ็นต์เปิดแอปและซิงค์กับแบ็กเอนด์ของ FCM ได้สำเร็จ ใช้กลยุทธ์ที่เหมาะสมโดยขึ้นอยู่กับ API ที่คุณใช้ ดังนี้
Firebase Installation ID API (แนะนำ)
สำหรับแอปไคลเอ็นต์ที่ใช้ FID API คุณไม่จำเป็นต้องกำหนดเวลางานเบื้องหลังเป็นระยะในแอปไคลเอ็นต์เพื่อดึงข้อมูลหรือรีเฟรชการลงทะเบียน SDK จะดูแลการรีเฟรชภายใต้การเริ่มต้นอัตโนมัติโดยอัตโนมัติ โดยจะส่ง FID ปัจจุบันที่ถูกต้องไปยัง Callback onRegistered() ของคุณเป็นประจำในการซิงค์ตามปกติระหว่างการเริ่มต้นแอป
หากต้องการอัปเดตเซิร์ฟเวอร์อยู่เสมอ ให้ใช้กลยุทธ์การอัปโหลดเมื่อเริ่มต้นระบบตามที่อธิบายไว้ในดึงข้อมูลและจัดเก็บรหัสการติดตั้ง Firebase ดังนี้
- เปิดใช้การเริ่มต้นอัตโนมัติ: SDK จะตรวจสอบโดยอัตโนมัติว่ามีการส่ง FID ล่าสุดไปยังเซิร์ฟเวอร์ของคุณในการซิงค์ตามปกติระหว่างการเริ่มต้นแอป
- การเริ่มต้นอัตโนมัติถูกปิดใช้หรือไม่รองรับ: เรียกใช้
register()เมื่อเริ่มต้นแอป (เช่น ใน Android ในonCreate()ของกิจกรรมหลัก) เพื่อบังคับลำดับการลงทะเบียนและทริกเกอร์การส่ง FID ไปยัง CallbackonRegistered()ของคุณ
กลยุทธ์เหล่านี้ช่วยรับประกันว่าเซิร์ฟเวอร์ของคุณจะมี FID ที่ใช้งานอยู่ล่าสุดเสมอ และสามารถกู้คืนจากการอัปโหลดที่ล้มเหลวได้โดยอัตโนมัติ ซึ่งทำให้แอปพลิเคชันมีความยืดหยุ่นสูง
API โทเค็นการลงทะเบียนที่เลิกใช้งานแล้ว
หากคุณใช้โทเค็นการลงทะเบียนเดิม SDK ของไคลเอ็นต์จะไม่จัดการการรีเฟรชในการซิงค์ตามกิจวัตรโดยอัตโนมัติ ดังนั้น เราขอแนะนำให้คุณดึงข้อมูลและอัปเดตโทเค็นการลงทะเบียนทั้งหมดในเซิร์ฟเวอร์เป็นระยะๆ โดยคุณต้องดำเนินการดังนี้
- เพิ่มตรรกะของแอปในแอปไคลเอ็นต์เพื่อดึงข้อมูลโทเค็นปัจจุบันโดยใช้การเรียก API ที่เหมาะสม (เช่น
token(completion):สำหรับแพลตฟอร์ม Apple หรือgetToken()สำหรับ Android) จากนั้นส่งโทเค็นปัจจุบันไปยังเซิร์ฟเวอร์แอปเพื่อจัดเก็บ (พร้อมการประทับเวลา) ซึ่งอาจเป็นงานรายเดือนที่กำหนดค่าให้ครอบคลุมลูกค้าหรือโทเค็นทั้งหมด - เพิ่มตรรกะเซิร์ฟเวอร์เพื่ออัปเดตการประทับเวลาของโทเค็นตามช่วงเวลาที่สม่ำเสมอ ไม่ว่าโทเค็นจะมีการเปลี่ยนแปลงหรือไม่ก็ตาม
ดูตัวอย่างตรรกะ Android สำหรับการอัปเดตโทเค็นเดิมโดยใช้ WorkManager ได้ที่การจัดการโทเค็น Cloud Messaging ในบล็อก Firebase
ไม่ว่าคุณจะใช้รูปแบบเวลาใด โปรดอัปเดตโทเค็นเป็นระยะๆ ความถี่ในการอัปเดตเดือนละครั้งจะสร้างสมดุลที่ดีระหว่างผลกระทบต่อแบตเตอรี่และการตรวจหาโทเค็นการลงทะเบียนที่ไม่มีการใช้งาน การรีเฟรชนี้ยังช่วยให้มั่นใจได้ว่าอุปกรณ์ที่ไม่มีการใช้งานจะรีเฟรชการลงทะเบียนเมื่อกลับมาใช้งานอีกครั้ง การรีเฟรชบ่อยกว่าสัปดาห์ละครั้งไม่ได้มีประโยชน์อะไร
นำการลงทะเบียนที่ไม่มีการใช้งานออก
ก่อนส่งข้อความไปยังอุปกรณ์ โปรดตรวจสอบว่าการประทับเวลาของการลงทะเบียนอุปกรณ์อยู่ภายในระยะเวลาที่ไม่มีการใช้งาน ตัวอย่างเช่น คุณสามารถใช้ Cloud Functions for Firebase เพื่อเรียกใช้การตรวจสอบรายวันเพื่อให้แน่ใจว่าการประทับเวลาอยู่ภายในระยะเวลาที่ไม่มีการอัปเดตที่กำหนด เช่น const
EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 30; แล้วนำการลงทะเบียนที่ไม่มีการอัปเดตออก ดังนี้
exports.pruneRegistrations = functions.pubsub.schedule('every 24 hours').onRun(async (context) => {
// Get all documents where the timestamp exceeds is not within the past month
const staleRegistrationsResult = await admin.firestore().collection('fcmRegistrations')
.where("timestamp", "<", Date.now() - EXPIRATION_TIME)
.get();
// Delete devices with stale registrations
staleRegistrationsResult.forEach(function(doc) { doc.ref.delete(); });
});
ยกเลิกการลงทะเบียนที่ไม่มีการใช้งานจากหัวข้อ
หากใช้หัวข้อ คุณอาจต้องยกเลิกการสมัครรับข้อมูลที่ไม่มีการใช้งานจากหัวข้อที่สมัครรับข้อมูลไว้ด้วย ซึ่งมี 2 ขั้นตอนดังนี้
- แอปควรสมัครรับข้อมูลหัวข้ออีกครั้งเมื่อรหัสการติดตั้ง Firebase (FID) มีการเปลี่ยนแปลง ซึ่งจะช่วยให้การสมัครใช้บริการปรากฏขึ้นอีกครั้งโดยอัตโนมัติเมื่อแอปกลับมาใช้งานได้อีกครั้ง
- หากอินสแตนซ์แอปไม่มีการใช้งานเป็นเวลา 1 เดือน (หรือกรอบเวลาความล้าสมัยของคุณเอง) คุณควรยกเลิกการสมัครรับข้อมูลจากหัวข้อโดยใช้ Firebase Admin SDK เพื่อลบรหัสการติดตั้ง Firebase ไปยังการแมปหัวข้อจากแบ็กเอนด์ FCM
ประโยชน์ของ 2 ขั้นตอนนี้คือการกระจายข้อความจะเกิดขึ้นเร็วขึ้นเนื่องจากมีการลงทะเบียนที่ไม่มีการใช้งานน้อยลง และอินสแตนซ์แอปที่ไม่มีการใช้งานจะสมัครใช้บริการอีกครั้งโดยอัตโนมัติเมื่อกลับมาใช้งานอีกครั้ง
วัดความสำเร็จของการแสดงโฆษณา
เพื่อให้เห็นภาพการส่งข้อความที่แม่นยำที่สุด คุณควรส่งข้อความไปยังอินสแตนซ์แอปที่มีการใช้งานอยู่เท่านั้น ซึ่งสำคัญอย่างยิ่งหากคุณส่งข้อความไปยังหัวข้อที่มีผู้สมัครรับข้อมูลจำนวนมากเป็นประจำ หากผู้สมัครรับข้อมูลบางส่วนไม่ได้ใช้งานจริง ผลกระทบต่อสถิติการนำส่งอาจมีนัยสำคัญเมื่อเวลาผ่านไป
ก่อนกำหนดเป้าหมายข้อความไปยังอินสแตนซ์ของแอป ให้พิจารณาสิ่งต่อไปนี้
- Google Analytics, ข้อมูลที่บันทึกใน BigQuery หรือสัญญาณการติดตามอื่นๆ บ่งชี้ว่าการลงทะเบียนทำงานอยู่หรือไม่
- การพยายามนำส่งก่อนหน้านี้ล้มเหลวอย่างต่อเนื่องเป็นระยะเวลาหนึ่งหรือไม่
- รหัสการติดตั้ง Firebase ได้รับการอัปเดตในเซิร์ฟเวอร์ของคุณในช่วงเดือนที่ผ่านมาหรือไม่
- สำหรับอุปกรณ์ Android FCM Data API รายงานเปอร์เซ็นต์การนำส่งข้อความที่ล้มเหลวสูงเนื่องจาก
droppedDeviceInactiveใช่ไหม
ดูข้อมูลเพิ่มเติมเกี่ยวกับการนำส่งได้ที่ทำความเข้าใจการนำส่งข้อความ