סביבת השרת שלך ו-FCM

צד השרת של Firebase Cloud Messaging מורכב משני רכיבים:

  • ה- FCM הקצה המסופק על ידי Google.
  • שרת האפליקציות שלך או סביבת שרת מהימנה אחרת שבה פועלת לוגיקת השרת שלך, כגון Cloud Functions for Firebase או סביבות ענן אחרות המנוהלות על ידי Google.

שרת האפליקציות או סביבת השרת המהימנה שלך שולחים בקשות להודעות ל-FCM העורפי, אשר מנתב הודעות לאפליקציות לקוח הפועלות במכשירים של המשתמשים.

דרישות לסביבת השרת המהימנה

סביבת שרת האפליקציה שלך חייבת לעמוד בקריטריונים הבאים:

  • מסוגל לשלוח בקשות הודעות מעוצבות כהלכה אל ה-backend של FCM.
  • מסוגל לטפל בבקשות ולשלוח אותן מחדש באמצעות גיבוי אקספוננציאלי.
  • מסוגל לאחסן בצורה מאובטחת אישורי הרשאת שרת ואסימוני רישום לקוח.
  • עבור פרוטוקול XMPP (אם נעשה בו שימוש), השרת חייב להיות מסוגל ליצור מזהי הודעות כדי לזהות באופן ייחודי כל הודעה שהוא שולח (הקצה האחורי של HTTP של FCM יוצר מזהי הודעות ומחזיר אותם בתגובה). מזהי הודעות XMPP צריכים להיות ייחודיים לכל מזהה שולח.

בחירת אפשרות שרת

תצטרך להחליט על דרך לקיים אינטראקציה עם שרתי FCM: או באמצעות Firebase Admin SDK או הפרוטוקולים הגולמיים. בגלל התמיכה שלו בשפות תכנות פופולריות ושיטות הנוחות שלו לטיפול באימות והרשאה, Firebase Admin SDK היא השיטה המומלצת.

האפשרויות לאינטראקציה עם שרתי FCM כוללות את הדברים הבאים:
  • Firebase Admin SDK, שיש לו תמיכה ב- Node , Java , Python , C# ו- Go .
  • FCM HTTP v1 API , שהוא העדכני ביותר מבין אפשרויות הפרוטוקול, עם הרשאה מאובטחת יותר ויכולות גמישות של העברת הודעות חוצות-פלטפורמות (SDK Admin של Firebase מבוסס על פרוטוקול זה ומספק את כל היתרונות הגלומים בו). מכיוון שתכונות חדשות בדרך כלל מתווספות לממשק ה-API של HTTP v1 בלבד, אנו ממליצים להשתמש ב-API זה לרוב מקרי השימוש.
  • פרוטוקול HTTP מדור קודם . פרויקטים חדשים מומלץ מאוד לאמץ את FCM v1 HTTP API במקום את הפרוטוקול הישן.
  • פרוטוקול שרת XMPP מדור קודם . פרויקטים חדשים מומלץ מאוד לאמץ את FCM v1 HTTP API במקום את הפרוטוקול הישן.

Firebase Admin SDK עבור FCM

ה-API של Admin FCM מטפל באימות עם הקצה העורפי ומקל על שליחת הודעות וניהול מנויי נושא. עם Firebase Admin SDK, אתה יכול:

  • שלח הודעות למכשירים בודדים
  • שלח הודעות לנושאים והצהרות תנאים התואמות נושא אחד או יותר.
  • הירשם ובטל את הרישום של מכשירים לנושאים וממנו
  • בנו מטענים של מסרים המותאמים לפלטפורמות יעד שונות

Admin Node.js SDK מספק שיטות לשליחת הודעות לקבוצות מכשירים.

כדי להגדיר את Firebase Admin SDK, ראה הוסף את Firebase Admin SDK לשרת שלך . אם כבר יש לך פרויקט Firebase, התחל עם הוסף את ה-SDK . כמו כן, הקפד להפעיל את Cloud Messagin API בדף ההגדרות של Cloud Messaging עבור הפרויקט שלך. לאחר מכן, לאחר התקנת Firebase Admin SDK, תוכל להתחיל לכתוב לוגיקה לבניית בקשות שליחה .

פרוטוקולי שרת FCM

נכון לעכשיו FCM מספקת את פרוטוקולי השרת הגולמיים הבאים:

שרת האפליקציות שלך יכול להשתמש בפרוטוקולים האלה בנפרד או במקביל. מכיוון שהוא המעודכן והגמיש ביותר לשליחת הודעות לפלטפורמות מרובות, ה-API של FCM HTTP v1 מומלץ בכל מקום אפשרי. אם הדרישות שלך כוללות העברת הודעות במעלה הזרם ממכשירים לשרת, תצטרך ליישם את פרוטוקול XMPP.

העברת הודעות XMPP שונה מהודעות HTTP בדרכים הבאות:

  • הודעות במעלה או במורד הזרם
    • HTTP: במורד הזרם בלבד, ענן למכשיר.
    • XMPP: במעלה ומורד (מכשיר לענן, ענן למכשיר).
  • העברת הודעות (סינכרוני או אסינכרוני)
    • HTTP: סינכרוני. שרתי אפליקציות שולחים הודעות כבקשות HTTP POST ומחכים לתגובה. מנגנון זה הינו סינכרוני וחוסם את השולח מלשלוח הודעה נוספת עד לקבלת התגובה.
    • XMPP: אסינכרוני. שרתי אפליקציות שולחים/מקבלים הודעות אל/מכל המכשירים שלהם במהירות קו מלאה דרך חיבורי XMPP מתמשכים. שרת החיבור XMPP שולח הודעות אישור או כשל (בצורה של הודעות XMPP מיוחדות מקודדות ACK ו-NACK JSON) באופן אסינכרוני.
  • JSON
    • HTTP: הודעות JSON נשלחות כ-HTTP POST.
    • XMPP: הודעות JSON מובלעות בהודעות XMPP.
  • טקסט רגיל
    • HTTP: הודעות טקסט רגילות שנשלחו כ-HTTP POST.
    • XMPP: לא נתמך.
  • שידור ריבוי במורד הזרם שליחה למספר אסימוני רישום.
    • HTTP: נתמך בפורמט הודעות JSON.
    • XMPP: לא נתמך.

הטמעת פרוטוקול שרת HTTP

כדי לשלוח הודעה, שרת האפליקציה מוציא בקשת POST עם כותרת HTTP וגוף HTTP המורכב מזוגות ערכי מפתח JSON. לפרטים על אפשרויות הכותרת והגוף, ראה בניית בקשות שליחת שרת אפליקציות

הטמעת פרוטוקול שרת XMPP

עומס ה-JSON עבור הודעות FCM דומה לפרוטוקול HTTP, עם החריגים הבאים:

  • אין תמיכה במספר נמענים.
  • FCM מוסיף את השדה message_id , אשר נדרש. מזהה זה מזהה באופן ייחודי את ההודעה בחיבור XMPP. ה-ACK או NACK מ-FCM משתמשים ב- message_id כדי לזהות הודעה שנשלחה משרתי אפליקציות ל-FCM. לכן, חשוב שה- message_id הזה לא רק יהיה ייחודי ( למזהה שולח ), אלא תמיד קיים.
  • XMPP משתמש במפתח השרת כדי לאשר חיבור מתמשך ל-FCM. ראה אישור שליחת בקשות למידע נוסף.

בנוסף להודעות FCM רגילות, נשלחות הודעות בקרה, המסומנות בשדה message_type באובייקט JSON. הערך יכול להיות 'ack' או 'nack', או 'control' (ראה פורמטים למטה). השרת שלך יכול להתעלם מכל הודעת FCM עם סוג message_type לא ידוע.

עבור כל הודעת מכשיר ששרת האפליקציה שלך מקבל מ-FCM, הוא צריך לשלוח הודעת ACK. זה אף פעם לא צריך לשלוח הודעת NACK. אם לא תשלח ACK עבור הודעה, FCM ישלח אותה מחדש בפעם הבאה שנוצר חיבור XMPP חדש, אלא אם ההודעה פג תחילה.

FCM גם שולח ACK או NACK עבור כל הודעת שרת למכשיר. אם גם אתה לא מקבל, זה אומר שחיבור ה-TCP נסגר באמצע הפעולה והשרת שלך צריך לשלוח מחדש את ההודעות. ראה בקרת זרימה לפרטים.

עיין בהפניה לפרוטוקול לקבלת רשימה של כל פרמטרי ההודעה.

פורמט בקשה

הודעה עם מטען — הודעת התראה

הנה בית XMPP להודעת התראה:

<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 המכיל את הודעת 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 צורות שונות שההודעה יכולה לקבל, המתוארים להלן.

הודעת ACK

הנה בית XMPP המכיל את הודעת 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>

עיין ב- Server Reference לקבלת רשימה מלאה של קודי השגיאה של NACK. אלא אם צוין אחרת, אין לנסות שוב הודעת NACKed. יש להתייחס לקודי שגיאה בלתי צפויים של NACK כמו INTERNAL_SERVER_ERROR .

שגיאת סטנזה

אתה יכול גם לקבל שגיאת בית במקרים מסוימים. שגיאת בית מכיל:

  • קוד שגיאה של סטנזה.
  • תיאור שגיאה של סטנזה (טקסט חופשי).

לדוגמה:

<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 אחר, ולפתוח חיבור חדש במידת הצורך. עם זאת, עליך להשאיר את החיבור המקורי פתוח ולהמשיך לקבל הודעות שעלולות להגיע דרך החיבור (ולחסום אותן) - 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:

תרשים מפורט של זרימת הבקרה בין FCM לשרת האפליקציה

איור 1. זרימת הודעה/קבלה.

לעומת זאת, כדי למנוע עומס יתר על שרת האפליקציות, FCM מפסיק לשלוח אם יש יותר מדי הודעות לא מאושרות. לכן, שרת האפליקציה צריך "ACK" הודעות במעלה הזרם, המתקבלות מאפליקציית הלקוח באמצעות FCM, בהקדם האפשרי כדי לשמור על זרימה קבועה של הודעות נכנסות. מגבלת ההודעות הממתינות שהוזכרה לעיל אינה חלה על ACKs אלה. גם אם ספירת ההודעות הממתינות מגיעה ל-100, שרת האפליקציה צריך להמשיך לשלוח ACKs עבור הודעות שהתקבלו מ-FCM כדי למנוע חסימת מסירה של הודעות חדשות במעלה הזרם.

ACKs תקפים רק בהקשר של חיבור אחד. אם החיבור נסגר לפני שניתן לסגור הודעה, שרת האפליקציה צריך להמתין עד ש-FCM ישלח מחדש את ההודעה במעלה הזרם לפני שהוא יחזיר אותה שוב. באופן דומה, יש לשלוח שוב את כל ההודעות הממתינות שעבורן לא התקבל ACK/NACK מ-FCM לפני סגירת החיבור.