การสมัครรับหัวข้อเป็นกลไกของ Firebase Cloud Messaging ที่ช่วยให้สามารถจัดกลุ่มอุปกรณ์ตามความสนใจและส่งการแจ้งเตือนไปยังหมวดหมู่ผู้สมัครรับข้อมูลทั้งหมด แทนที่จะส่งไปยัง Registration Token แต่ละรายการหลายพันรายการ เพียงส่งข้อความเดียวไปยังหัวข้อก็เพียงพอ ตามข้อมูลจาก Firebase, 2025 การสมัครรับหัวข้อ ถูกใช้ในแอปข่าว การถ่ายทอดสดกีฬา และแคมเปญการตลาดสำหรับการส่งการแจ้งเตือนในวงกว้าง
ประเด็นสำคัญ
การสมัครรับหัวข้อ เป็นกลไกการส่งการแจ้งเตือนแบบ Push แบบกลุ่มที่อุปกรณ์สมัครรับช่องที่มีชื่อ (หัวข้อ) และรับข้อความที่ส่งไปยังช่องเหล่านั้น แต่ละหัวข้อถูกระบุด้วยชื่อสตริง เช่น news_sports หรือ weather_alerts
เมื่ออุปกรณ์สมัครรับหัวข้อ FCM จะเพิ่ม Registration Token ของอุปกรณ์เข้าไปในรายชื่อผู้รับของหัวข้อนั้น เมื่อส่งข้อความไปยังหัวข้อ FCM จะกำหนดเส้นทางสำเนาไปยังอุปกรณ์ที่สมัครรับแต่ละเครื่องโดยอัตโนมัติ Firebase ไม่จำกัดจำนวนการสมัครต่ออุปกรณ์ — แอปสามารถสมัครให้ผู้ใช้รับหัวข้อนับสิบหัวข้อพร้อมกันได้
ข้อได้เปรียบหลักของหัวข้อคือความสามารถในการปรับขนาด ในการส่งการแจ้งเตือนไปยังผู้ใช้หนึ่งล้านคน เพียงคำขอ HTTP เดียวไปยัง FCM พร้อมชื่อหัวข้อก็เพียงพอ สำหรับการส่งรายบุคคล จะต้องใช้คำขอหนึ่งล้านคำขอหรือการส่งแบบแบตช์สูงสุด 500 โทเค็นต่อครั้ง หัวข้อยังทำให้ตรรกะฝั่งเซิร์ฟเวอร์ง่ายขึ้น — ไม่จำเป็นต้องจัดเก็บรายการโทเค็นสำหรับแต่ละหมวดหมู่
| พารามิเตอร์ | การส่งรายบุคคล | การสมัครรับหัวข้อ |
|---|---|---|
| จำนวนคำขอ | หนึ่งรายการต่อโทเค็นหรือแบตช์สูงสุด 500 | หนึ่งรายการต่อหัวข้อ |
| การจัดการการสมัคร | บนเซิร์ฟเวอร์ (รายการโทเค็น) | บนไคลเอ็นต์หรือเซิร์ฟเวอร์ |
| กลุ่มแบบไดนามิก | ต้องอัปเดตรายการ | อัตโนมัติผ่านการสมัคร |
| ขีดจำกัดผู้รับ | สูงสุด 500 ต่อคำขอ | ไม่จำกัด |
การสมัครรับหัวข้อถูกใช้อย่างแพร่หลายในแอปข่าวสำหรับการจัดหมวดหมู่เนื้อหา — การสมัครรับหัวข้อ “กีฬา” “การเมือง” “เทคโนโลยี” ช่วยให้ส่งการแจ้งเตือนที่เกี่ยวข้อง ในอีคอมเมิร์ซ หัวข้อถูกใช้สำหรับการแจ้งเตือนเกี่ยวกับส่วนลดในหมวดหมู่สินค้าเฉพาะ ในแอปส่งข้อความและโซเชียลเน็ตเวิร์ก หัวข้อถูกใช้สำหรับการแจ้งเตือนเกี่ยวกับเหตุการณ์ในกลุ่ม
Firebase กำหนดข้อจำกัดในการทำงานกับหัวข้อ แอปเดียวสามารถมีได้สูงสุด 2000 หัวข้อ อุปกรณ์แต่ละเครื่องสามารถสมัครรับได้ไม่เกิน 2000 หัวข้อ ความถี่ของการดำเนินการสมัคร/ยกเลิกการสมัครก็ถูกจำกัดเช่นกัน — ไม่เกิน 3000 การดำเนินการต่อนาทีต่อโปรเจกต์ การเกินขีดจำกัดเหล่านี้จะส่งผลให้ถูกบล็อกชั่วคราว สำหรับโปรเจกต์ที่มีหัวข้อจำนวนมาก แนะนำให้ใช้เงื่อนไข (condition) แทนหัวข้อ — FCM รองรับนิพจน์เชิงตรรกะสำหรับการกำหนดเป้าหมาย
กระบวนการสมัครรับหัวข้อ ประกอบด้วยสามขั้นตอน: การเริ่มต้นการสมัครบนไคลเอ็นต์ การลงทะเบียนในโครงสร้างพื้นฐาน FCM และการยืนยันการดำเนินการ หลังจากการสมัครสำเร็จ อุปกรณ์จะเริ่มรับข้อความที่ส่งไปยังหัวข้อนั้น
เมื่อไคลเอ็นต์เรียกเมธอด subscribeToTopic() Firebase SDK จะส่งคำขอไปยังเซิร์ฟเวอร์ FCM เซิร์ฟเวอร์ตรวจสอบความถูกต้องของการดำเนินการและเพิ่มโทเค็นของอุปกรณ์ในรายชื่อผู้สมัครรับหัวข้อ FCM ส่งการยืนยันการสมัครที่สำเร็จกลับไปยังไคลเอ็นต์ จากจุดนี้เป็นต้นไป ข้อความทั้งหมดที่ส่งไปยังหัวข้อนี้จะถูกส่งไปยังอุปกรณ์
ไม่จำเป็นต้องสร้างหัวข้อล่วงหน้าในคอนโซล Firebase เมื่ออุปกรณ์เครื่องแรกสมัครรับหัวข้อชื่อ news_promo FCM จะสร้างขึ้นโดยอัตโนมัติ หากอุปกรณ์เครื่องสุดท้ายยกเลิกการสมัคร หัวข้อจะยังคงอยู่ในระบบแต่ไม่ทำงาน และจะกลับมาทำงานอีกครั้งเมื่อมีการสมัครใหม่
บน Android การสมัครและยกเลิกการสมัครหัวข้อดำเนินการผ่าน FirebaseMessaging SDK เมธอด subscribeToTopic() และ unsubscribeFromTopic() รับชื่อหัวข้อเป็นพารามิเตอร์ การดำเนินการเป็นแบบอะซิงโครนัสและต้องการการจัดการผลลัพธ์
ในการสมัคร เพียงเรียก subscribeToTopic() พร้อมชื่อหัวข้อเป้าหมาย Firebase SDK จัดการคำขอเครือข่ายและลองใหม่โดยอัตโนมัติเมื่อเกิดข้อผิดพลาด ขอแนะนำให้สมัครรับหัวข้อหลังจากได้รับ Registration Token สำเร็จแล้ว
class TopicSubscriber(private val context: Context) {
fun subscribeToNewsTopic() {
FirebaseMessaging.getInstance()
.subscribeToTopic("news_latest")
.addOnCompleteListener { task ->
val msg = if (task.isSuccessful) {
"Subscribed to news topic"
} else {
"Subscription failed"
}
Log.d("FCM", msg)
}
}
fun unsubscribeFromNewsTopic() {
FirebaseMessaging.getInstance()
.unsubscribeFromTopic("news_latest")
.addOnCompleteListener { task ->
Log.d("FCM", "ยกเลิกการสมัครแล้ว: ${task.isSuccessful}")
}
}
}
ในแอปจริง ผู้ใช้อาจสมัครรับหลายหมวดหมู่ เพื่อการจัดการที่สะดวก ให้สร้างคลาสผู้จัดการ ที่ซิงโครไนซ์สถานะการสมัครกับฝั่งเซิร์ฟเวอร์ เมื่อผู้ใช้เข้าสู่ระบบ ให้กู้คืนการสมัครของพวกเขาจากโปรไฟล์
class SubscriptionManager(private val context: Context) {
private val fcm = FirebaseMessaging.getInstance()
suspend fun syncSubscriptions(topics: List<String>) {
topics.forEach { topic ->
fcm.subscribeToTopic(topic).await()
}
}
suspend fun removeAllSubscriptions() {
val savedTopics = getSavedTopics()
savedTopics.forEach { topic ->
fcm.unsubscribeFromTopic(topic).await()
}
}
private fun getSavedTopics(): List<String> {
return listOf("news_latest", "promotions", "updates")
}
}
บน iOS กระบวนการสมัครรับหัวข้อเหมือนกับ Android ในเชิงตรรกะ แต่ใช้ Swift API ของ Firebase Messaging เมธอด subscribe และ unsubscribe ถูกเรียกบนอินสแตนซ์ของ Messaging และเป็นแบบอะซิงโครนัสเช่นกัน
ในการสมัครรับหัวข้อในแอป iOS ให้ใช้เมธอด Messaging.subscribe() สิ่งสำคัญคือต้องเรียกการสมัครหลังจากการเริ่มต้น Firebase และรับ Registration Token แล้ว Apple แนะนำให้ขออนุญาตการแจ้งเตือนก่อนสมัครรับหัวข้อ
import FirebaseMessaging
class PushTopicManager {
func subscribeToTopic(topic: String) {
Messaging.messaging().subscribe(toTopic: topic) { error in
if let error = error {
Log.e("FCM", "ข้อผิดพลาดการสมัคร: \(error)")
} else {
Log.d("FCM", "สมัครรับ \(topic) แล้ว")
}
}
}
func unsubscribeFromTopic(topic: String) {
Messaging.messaging().unsubscribe(fromTopic: topic) { error in
if let error = error {
Log.e("FCM", "ข้อผิดพลาดการยกเลิกการสมัคร: \(error)")
}
}
}
}
บน iOS การสมัครรับหัวข้อยังเชื่อมโยงกับ Registration Token ที่ Firebase ได้รับจาก APNs หากโทเค็น APNs เปลี่ยนแปลง (เช่น หลังจากการกู้คืนอุปกรณ์) Firebase จะโอนย้ายการสมัครไปยังโทเค็นใหม่โดยอัตโนมัติ อย่างไรก็ตาม ในกรณีที่พบไม่บ่อย อาจต้องสมัครใหม่หลังจากการอัปเดต Registration Token
การจัดการฝั่งเซิร์ฟเวอร์ การสมัครช่วยให้สามารถสมัครและยกเลิกการสมัครอุปกรณ์ได้โดยไม่ต้องเกี่ยวข้องกับแอปไคลเอ็นต์ ซึ่งมีประโยชน์สำหรับการดูแลระบบ การทดสอบ A/B และการจัดการการสมัครฝั่ง backend
Firebase มี REST API สำหรับการจัดการการสมัครจำนวนมาก ปลายทาง /v1/projects/{project_id}/subscriptions อนุญาตให้สมัครได้สูงสุด 1000 อุปกรณ์ ต่อหนึ่งคำขอ API ใช้ Registration Token ของอุปกรณ์สำหรับการระบุตัวตน
const admin = require("firebase-admin")
async function subscribeUsersToTopic(tokens, topic) {
try {
const response = await admin
.messaging()
.subscribeToTopic(tokens, topic)
Log.info(`Success: ${response.successCount}`)
Log.info(`Failures: ${response.failureCount}`)
} catch (error) {
Log.error("ข้อผิดพลาดการสมัคร", error)
}
}
การจัดการการสมัครจากเซิร์ฟเวอร์ถูกใช้ในหลายสถานการณ์ เมื่อผู้ใช้ลงทะเบียน เซิร์ฟเวอร์จะสมัครให้พวกเขาในหัวข้อพื้นฐานโดยอัตโนมัติ เมื่อการตั้งค่าเปลี่ยนแปลงในเวอร์ชันเว็บ เซิร์ฟเวอร์จะซิงโครไนซ์การสมัครบนอุปกรณ์มือถือ ผู้ดูแลระบบ สามารถสมัครอุปกรณ์ทดสอบในหัวข้อภายในเพื่อการดีบัก สำหรับการดำเนินการจำนวนมาก FCM มีเมธอด Instance Group ซึ่งอนุญาตให้จัดการการสมัครของกลุ่มอุปกรณ์ผ่านตัวระบุกลุ่มเดียว
Firebase ไม่มี API ในตัวสำหรับตรวจสอบการสมัครปัจจุบันของอุปกรณ์ นักพัฒนาควรดูแลฐานข้อมูลการสมัครของตนเองบนฝั่งเซิร์ฟเวอร์ ทุกครั้งที่เปิดแอป ไคลเอ็นต์จะซิงโครไนซ์การสมัครกับเซิร์ฟเวอร์โดยส่งรายการหัวข้อที่ใช้งานอยู่ ซึ่งช่วยระบุการไม่ซิงโครไนซ์และกู้คืนการสมัครหากจำเป็น สำหรับการตรวจสอบ ให้ใช้บันทึกของ Firebase Cloud Functions — การดำเนินการ subscribe/unsubscribe แต่ละรายการสามารถบันทึกได้
คำถามที่พบบ่อย
จำนวนหัวข้อสูงสุดคือ 2000 หัวข้อต่อแอป หากต้องการมากกว่านี้ ให้พิจารณาใช้กลุ่มอุปกรณ์หรือการส่งรายบุคคลตามโทเค็น
Firebase ไม่มี API โดยตรงสำหรับรับรายการสมัครของอุปกรณ์ ขอแนะนำให้นักพัฒนาเก็บสถานะการสมัครบนเซิร์ฟเวอร์ของตนเองและซิงโครไนซ์กับไคลเอ็นต์
FCM จะส่งคืนผลลัพธ์ที่สำเร็จ Firebase จัดการการยกเลิกการสมัครจากหัวข้อที่ไม่มีอยู่เป็นการดำเนินการ no-op — ไม่มีข้อผิดพลาดเกิดขึ้น สถานะไม่เปลี่ยนแปลง
ได้ ในคอนโซล Firebase ในส่วน Cloud Messaging คุณสามารถเลือกหัวข้อเป็นกลุ่มเป้าหมายและส่งการแจ้งเตือนทดสอบหรือจริงผ่านอินเทอร์เฟซเว็บ
โดยปกติ การสมัครจะเริ่มทำงานภายในไม่กี่วินาที อย่างไรก็ตาม ในกรณีที่พบไม่บ่อย ความล่าช้าอาจถึง 30–60 วินาที เนื่องจากการกระจายข้อมูลผ่านเซิร์ฟเวอร์ FCM
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม