สภาพแวดล้อมเซิร์ฟเวอร์และ FCM ของคุณ
ฝั่งเซิร์ฟเวอร์ของ Firebase Cloud Messaging ประกอบด้วยสององค์ประกอบ:
- แบ็กเอนด์ FCM ที่ให้บริการโดย Google
- เซิร์ฟเวอร์แอป ของคุณหรือ สภาพแวดล้อมเซิร์ฟเวอร์ที่เชื่อถือได้ อื่นๆ ที่ลอจิกเซิร์ฟเวอร์ของคุณทำงาน เช่น Cloud Functions สำหรับ Firebase หรือสภาพแวดล้อมระบบคลาวด์อื่นๆ ที่จัดการโดย Google
เซิร์ฟเวอร์แอปหรือสภาพแวดล้อมเซิร์ฟเวอร์ที่เชื่อถือได้จะส่งคำขอข้อความไปยังแบ็กเอนด์ FCM ซึ่งจะกำหนดเส้นทางข้อความไปยังแอปไคลเอ็นต์ที่ทำงานบนอุปกรณ์ของผู้ใช้
ข้อกำหนดสำหรับสภาพแวดล้อมเซิร์ฟเวอร์ที่เชื่อถือได้
สภาพแวดล้อมเซิร์ฟเวอร์แอปของคุณต้องเป็นไปตามเกณฑ์ต่อไปนี้:
- สามารถส่งคำขอข้อความที่มีรูปแบบถูกต้องไปยังแบ็กเอนด์ FCM
- สามารถจัดการคำขอและส่งซ้ำได้โดยใช้ การย้อนกลับแบบเอ็กซ์โปเนนเชียล
- สามารถจัดเก็บข้อมูลการอนุญาตเซิร์ฟเวอร์และโทเค็นการลงทะเบียนไคลเอ็นต์ได้อย่างปลอดภัย
- สำหรับโปรโตคอล XMPP (หากใช้) เซิร์ฟเวอร์ต้องสามารถสร้างรหัสข้อความเพื่อระบุแต่ละข้อความที่ส่งโดยไม่ซ้ำกัน (แบ็กเอนด์ FCM HTTP จะสร้างรหัสข้อความและส่งกลับในการตอบกลับ) รหัสข้อความ XMPP ควรไม่ซ้ำกันสำหรับแต่ละรหัสผู้ส่ง
การเลือกตัวเลือกเซิร์ฟเวอร์
คุณจะต้องตัดสินใจเลือกวิธีโต้ตอบกับเซิร์ฟเวอร์ FCM โดยใช้ Firebase Admin SDK หรือโปรโตคอลดิบ เนื่องจากการรองรับในภาษาการเขียนโปรแกรมยอดนิยมและวิธีการที่สะดวกในการจัดการการตรวจสอบสิทธิ์และการให้สิทธิ์ Firebase Admin SDK จึงเป็นวิธีที่แนะนำ
ตัวเลือกสำหรับการโต้ตอบกับเซิร์ฟเวอร์ FCM มีดังต่อไปนี้:
- Firebase Admin SDK ซึ่งรองรับ Node , Java , Python , C# และ Go
- FCM HTTP v1 API ซึ่งเป็นตัวเลือกโปรโตคอลล่าสุด พร้อมการให้สิทธิ์ที่ปลอดภัยยิ่งขึ้นและ ความสามารถในการรับส่งข้อความข้ามแพลตฟอร์ม ที่ยืดหยุ่น (Firebase Admin SDK ใช้โปรโตคอลนี้และมีข้อดีทั้งหมดในตัว) เนื่องจากโดยปกติแล้วคุณลักษณะใหม่จะเพิ่มให้กับ HTTP v1 API เท่านั้น เราจึงแนะนำให้ใช้ API นี้กับกรณีการใช้งานส่วนใหญ่
- โปรโตคอล HTTP เดิม ขอแนะนำให้โปรเจ็กต์ใหม่ใช้ FCM v1 HTTP API แทนโปรโตคอลเดิม
- โปรโตคอลเซิร์ฟเวอร์ XMPP เดิม ขอแนะนำให้โปรเจ็กต์ใหม่ใช้ FCM v1 HTTP API แทนโปรโตคอลเดิม
Firebase Admin SDK สำหรับ FCM
Admin FCM API จัดการการรับรองความถูกต้องด้วยแบ็กเอนด์และอำนวยความสะดวกในการส่งข้อความและจัดการการสมัครหัวข้อ ด้วย Firebase Admin SDK คุณสามารถ:
- ส่งข้อความไปยังอุปกรณ์แต่ละเครื่อง
- ส่งข้อความไปยังหัวข้อและข้อความแสดงเงื่อนไขที่ตรงกับหนึ่งหัวข้อขึ้นไป
- สมัครและยกเลิกการสมัครอุปกรณ์เข้าและออกจากหัวข้อ
- สร้างเพย์โหลดข้อความที่เหมาะกับแพลตฟอร์มเป้าหมายต่างๆ
Admin Node.js SDK มีวิธีการส่งข้อความไปยังกลุ่มอุปกรณ์
หากต้องการตั้งค่า Firebase Admin SDK โปรดดู เพิ่ม Firebase Admin SDK ไปยังเซิร์ฟเวอร์ของคุณ หากคุณมีโปรเจ็กต์ Firebase อยู่แล้ว ให้เริ่มด้วย Add the SDK นอกจากนี้ ตรวจสอบให้แน่ใจว่าได้เปิดใช้งาน Cloud Messagin API ใน หน้าการตั้งค่า Cloud Messaging สำหรับโครงการของคุณ จากนั้น เมื่อติดตั้ง Firebase Admin SDK แล้ว คุณสามารถเริ่มเขียนตรรกะเพื่อ สร้างคำขอส่ง
โปรโตคอลเซิร์ฟเวอร์ FCM
ปัจจุบัน FCM มีโปรโตคอลเซิร์ฟเวอร์ดิบเหล่านี้:
- FCM HTTP v1 API
- โปรโตคอล HTTP เดิม
- โปรโตคอล XMPP เดิม
เซิร์ฟเวอร์แอปของคุณสามารถใช้โปรโตคอลเหล่านี้แยกกันหรือใช้ควบคู่กันได้ เนื่องจากเป็นเวอร์ชันล่าสุดและยืดหยุ่นที่สุดสำหรับการส่งข้อความไปยังหลายแพลตฟอร์ม จึงแนะนำให้ใช้ FCM HTTP v1 API ในทุกที่ที่ทำได้ หากข้อกำหนดของคุณรวมถึงการส่งข้อความอัปสตรีมจากอุปกรณ์ไปยังเซิร์ฟเวอร์ คุณจะต้องใช้โปรโตคอล XMPP
ข้อความ XMPP แตกต่างจากข้อความ HTTP ในลักษณะต่อไปนี้:
- ข้อความต้นน้ำ/ปลายน้ำ
- HTTP: ดาวน์สตรีมเท่านั้น คลาวด์กับอุปกรณ์
- XMPP: ต้นน้ำและปลายน้ำ (ระหว่างอุปกรณ์กับคลาวด์, คลาวด์กับอุปกรณ์)
- ข้อความ (ซิงโครนัสหรืออะซิงโครนัส)
- HTTP: ซิงโครนัส เซิร์ฟเวอร์แอปส่งข้อความเป็นคำขอ HTTP POST และรอการตอบกลับ กลไกนี้เป็นแบบซิงโครนัสและบล็อกผู้ส่งไม่ให้ส่งข้อความอีกจนกว่าจะได้รับการตอบกลับ
- XMPP: อะซิงโครนัส เซิร์ฟเวอร์ของแอปส่ง/รับข้อความไปยัง/จากอุปกรณ์ทั้งหมดด้วยความเร็วเต็มสายผ่านการเชื่อมต่อ XMPP อย่างต่อเนื่อง เซิร์ฟเวอร์การเชื่อมต่อ XMPP ส่งการแจ้งเตือนการรับทราบหรือความล้มเหลว (ในรูปแบบของข้อความ XMPP ที่เข้ารหัส ACK และ NACK JSON พิเศษ) แบบอะซิงโครนัส
- เจสัน
- HTTP: ข้อความ JSON ที่ส่งเป็น HTTP POST
- XMPP: ข้อความ JSON ที่ห่อหุ้มอยู่ในข้อความ XMPP
- ข้อความธรรมดา
- HTTP: ข้อความธรรมดาที่ส่งเป็น HTTP POST
- XMPP: ไม่รองรับ
- Multicast downstream ส่งไปยังโทเค็นการลงทะเบียนหลายรายการ
- HTTP: รองรับในรูปแบบข้อความ JSON
- XMPP: ไม่รองรับ
การใช้โปรโตคอลเซิร์ฟเวอร์ HTTP
ในการส่งข้อความ เซิร์ฟเวอร์แอปจะออกคำขอ POST ที่มีส่วนหัว HTTP และเนื้อความ HTTP ที่ประกอบด้วยคู่ค่าคีย์ JSON สำหรับรายละเอียดเกี่ยวกับตัวเลือกส่วนหัวและเนื้อหา โปรดดูที่ Build App Server Send Requests
การใช้โปรโตคอลเซิร์ฟเวอร์ XMPP
เพย์โหลด JSON สำหรับข้อความ FCM คล้ายกับโปรโตคอล HTTP โดยมีข้อยกเว้นเหล่านี้:
- ไม่มีการสนับสนุนสำหรับผู้รับหลายคน
- FCM เพิ่มฟิลด์
message_id
ซึ่งจำเป็น ID นี้ระบุข้อความในการเชื่อมต่อ XMPP โดยไม่ซ้ำกัน ACK หรือ NACK จาก FCM ใช้message_id
เพื่อระบุข้อความที่ส่งจากเซิร์ฟเวอร์แอปไปยัง FCM ดังนั้นจึงเป็นเรื่องสำคัญที่message_id
นี้จะต้องไม่ซ้ำกัน (ต่อ ID ผู้ส่ง ) แต่จะต้องแสดงอยู่เสมอ - XMPP ใช้คีย์เซิร์ฟเวอร์เพื่ออนุญาตการเชื่อมต่อถาวรกับ FCM ดู ให้สิทธิ์ส่งคำขอ สำหรับข้อมูลเพิ่มเติม
นอกจากข้อความ FCM ทั่วไปแล้ว ข้อความควบคุมยังถูกส่ง ซึ่งระบุโดยฟิลด์ message_type
ในออบเจ็กต์ JSON ค่าสามารถเป็นได้ทั้ง 'ack' หรือ 'nack' หรือ 'control' (ดูรูปแบบด้านล่าง) เซิร์ฟเวอร์ของคุณสามารถละเว้นข้อความ FCM ใดๆ ที่มี message_type
ที่ไม่รู้จักได้
สำหรับแต่ละข้อความของอุปกรณ์ที่เซิร์ฟเวอร์แอปของคุณได้รับจาก FCM จะต้องส่งข้อความ ACK ไม่จำเป็นต้องส่งข้อความ NACK หากคุณไม่ส่ง ACK สำหรับข้อความ FCM จะส่งอีกครั้งในครั้งถัดไปที่สร้างการเชื่อมต่อ XMPP ใหม่ เว้นแต่ข้อความจะหมดอายุก่อน
FCM ยังส่ง ACK หรือ NACK สำหรับแต่ละข้อความระหว่างเซิร์ฟเวอร์ถึงอุปกรณ์ หากคุณไม่ได้รับอย่างใดอย่างหนึ่ง แสดงว่าการเชื่อมต่อ TCP ถูกปิดระหว่างการดำเนินการ และเซิร์ฟเวอร์ของคุณจำเป็นต้องส่งข้อความอีกครั้ง ดู การควบคุมการไหล สำหรับรายละเอียด
ดู การอ้างอิงโปรโตคอล สำหรับรายการพารามิเตอร์ข้อความทั้งหมด
ขอแบบ
ข้อความพร้อมเพย์โหลด — ข้อความแจ้งเตือน
นี่คือ XMPP stanza สำหรับข้อความแจ้งเตือน:
<message id=""> <gcm xmlns="google:mobile:data"> { "to":"REGISTRATION_ID", // "to" replaces "registration_ids" "notification": { "title": "Portugal vs. Denmark”, "body”: "5 to 1” }, "time_to_live":"600" } </gcm> </message>
ข้อความพร้อมเพย์โหลด — ข้อความข้อมูล
นี่คือ XMPP stanza ที่มีข้อความ JSON จากเซิร์ฟเวอร์แอปไปยัง FCM:
<message id=""> <gcm xmlns="google:mobile:data"> { "to":"REGISTRATION_ID", // "to" replaces "registration_ids" "message_id":"m-1366082849205" // new required field "data": { "hello":"world", } "time_to_live":"600", } </gcm> </message>
รูปแบบการตอบสนอง
การตอบสนอง FCM สามารถมีได้สามรูปแบบ ข้อความแรกคือข้อความ 'ack' ตามปกติ แต่เมื่อการตอบกลับมีข้อผิดพลาด มี 2 รูปแบบที่แตกต่างกันที่สามารถใช้ข้อความได้ ซึ่งอธิบายไว้ด้านล่าง
ตอบกลับข้อความ
นี่คือ XMPP stanza ที่มีข้อความ ACK/NACK จาก FCM ไปยังเซิร์ฟเวอร์แอป:
<message id=""> <gcm xmlns="google:mobile:data"> { "from":"REGID", "message_id":"m-1366082849205" "message_type":"ack" } </gcm> </message>
ข้อความ NACK
ข้อผิดพลาด NACK เป็นข้อความ XMPP ปกติที่ข้อความแสดงสถานะ message_type
คือ "nack" ข้อความ NACK ประกอบด้วย:
- รหัสข้อผิดพลาด NACK
- คำอธิบายข้อผิดพลาด NACK
ด้านล่างนี้คือตัวอย่างบางส่วน
การลงทะเบียนไม่ถูกต้อง:
<message> <gcm xmlns="google:mobile:data"> { "message_type":"nack", "message_id":"msgId1", "from":"SomeInvalidRegistrationToken", "error":"BAD_REGISTRATION", "error_description":"Invalid token on 'to' field: SomeInvalidRegistrationId" } </gcm> </message>
JSON ไม่ถูกต้อง:
<message> <gcm xmlns="google:mobile:data"> { "message_type":"nack", "message_id":"msgId1", "from":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...", "error":"INVALID_JSON", "error_description":"InvalidJson: JSON_TYPE_ERROR : Field \"time_to_live\" must be a JSON java.lang.Number: abc" } </gcm> </message>
อัตราข้อความของอุปกรณ์เกิน:
<message id="..."> <gcm xmlns="google:mobile:data"> { "message_type":"nack", "message_id":"msgId1", "from":"REGID", "error":"DEVICE_MESSAGE_RATE_EXCEEDED", "error_description":"Downstream message rate exceeded for this registration id" } </gcm> </message>
ดู การอ้างอิงเซิร์ฟเวอร์ สำหรับรายการรหัสข้อผิดพลาด NACK ทั้งหมด ข้อความ NACKed ไม่ควรลองใหม่ เว้นแต่จะระบุไว้เป็นอย่างอื่น รหัสข้อผิดพลาด NACK ที่ไม่คาดคิดควรได้รับการปฏิบัติเหมือนกับ INTERNAL_SERVER_ERROR
ข้อผิดพลาดของสแตนซา
นอกจากนี้ คุณยังสามารถได้รับข้อผิดพลาดของ stanza ในบางกรณี ข้อผิดพลาดของ stanza ประกอบด้วย:
- รหัสข้อผิดพลาดของ Stanza
- คำอธิบายข้อผิดพลาดของ Stanza (ข้อความอิสระ)
ตัวอย่างเช่น:
<message id="3" type="error" to="123456789@fcm.googleapis.com/ABC"> <gcm xmlns="google:mobile:data"> {"random": "text"} </gcm> <error code="400" type="modify"> <bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/> <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"> InvalidJson: JSON_PARSING_ERROR : Missing Required Field: message_id\n </text> </error> </message>
ควบคุมข้อความ
FCM จำเป็นต้องปิดการเชื่อมต่อเป็นระยะเพื่อดำเนินการโหลดบาลานซ์ ก่อนที่จะปิดการเชื่อมต่อ FCM จะส่งข้อความ CONNECTION_DRAINING
เพื่อระบุว่าการเชื่อมต่อกำลังหมดและจะปิดในไม่ช้า "การระบายน้ำ" หมายถึงการปิดการไหลของข้อความที่เข้ามาในการเชื่อมต่อ แต่อนุญาตให้สิ่งใดก็ตามที่อยู่ในไปป์ไลน์ดำเนินการต่อ เมื่อคุณได้รับข้อความ CONNECTION_DRAINING
คุณควรเริ่มส่งข้อความไปยังการเชื่อมต่อ FCM อื่นทันที โดยเปิดการเชื่อมต่อใหม่หากจำเป็น อย่างไรก็ตาม คุณควรเปิดการเชื่อมต่อเดิมไว้และรับข้อความที่อาจมาผ่านการเชื่อมต่อต่อไป (และทำการ ACKing พวกเขา)—FCM จะจัดการการเริ่มต้นการเชื่อมต่อให้ปิดเมื่อพร้อม
ข้อความ CONNECTION_DRAINING
มีลักษณะดังนี้:
<message> <data:gcm xmlns:data="google:mobile:data"> { "message_type":"control" "control_type":"CONNECTION_DRAINING" } </data:gcm> </message>
ขณะนี้ CONNECTION_DRAINING
เป็น control_type
เดียวที่รองรับ
การควบคุมการไหล
ทุกข้อความที่ส่งไปยัง FCM จะได้รับการตอบกลับแบบ ACK หรือ NACK ข้อความที่ไม่ได้รับการตอบกลับเหล่านี้ถือว่ารอดำเนินการ หากจำนวนข้อความที่รอดำเนินการถึง 100 เซิร์ฟเวอร์ของแอปควรหยุดส่งข้อความใหม่และรอให้ FCM รับทราบข้อความบางส่วนที่รอดำเนินการดังแสดงในรูปที่ 1:
รูปที่ 1 ข้อความ/กระแสตอบรับ
ในทางกลับกัน เพื่อหลีกเลี่ยงการโอเวอร์โหลดเซิร์ฟเวอร์แอป FCM จะหยุดส่งหากมีข้อความที่ไม่ได้รับการยอมรับมากเกินไป ดังนั้น เซิร์ฟเวอร์แอปควร "ACK" ข้อความอัพสตรีมที่ได้รับจากแอปพลิเคชันไคลเอนต์ผ่าน FCM โดยเร็วที่สุดเพื่อรักษากระแสข้อความขาเข้าให้คงที่ ขีดจำกัดข้อความที่ค้างอยู่ข้างต้นไม่มีผลกับ ACK เหล่านี้ แม้ว่าจำนวนข้อความที่รอดำเนินการจะถึง 100 เซิร์ฟเวอร์แอปควรส่ง ACK ต่อไปสำหรับข้อความที่ได้รับจาก FCM เพื่อหลีกเลี่ยงการบล็อกการส่งข้อความอัปสตรีมใหม่
ACKs ใช้ได้เฉพาะในบริบทของการเชื่อมต่อเดียวเท่านั้น หากการเชื่อมต่อถูกปิดก่อนที่จะสามารถ ACKed ข้อความได้ เซิร์ฟเวอร์แอปควรรอให้ FCM ส่งข้อความ upstream อีกครั้งก่อนที่จะทำการ acking อีกครั้ง ในทำนองเดียวกัน ข้อความที่รอดำเนินการทั้งหมดซึ่งไม่ได้รับ ACK/NACK จาก FCM ก่อนที่การเชื่อมต่อจะถูกปิดควรถูกส่งอีกครั้ง