מפרט הפרוטוקול עבור https.onCall

טריגר https.onCall ב-Cloud Functions הוא טריגר HTTPS עם פורמט ספציפי לבקשה ולתגובה. בקטע הזה מפורטת מפרטת הפורמטים של הבקשות והתשובות ב-HTTPS שבהם משתמשים ערכות ה-SDK של הלקוח כדי להטמיע את ה-API. המידע הזה יכול להיות שימושי אם אי אפשר לעמוד בדרישות שלכם באמצעות פלטפורמות Android או Apple או ערכות SDK לאינטרנט.

פורמט הבקשה: כותרות

בקשת ה-HTTP לנקודת קצה של טריגר שניתן לקריאה חייבת להיות POST עם הכותרות הבאות:

  • חובה: Content-Type: application/json
    • אפשר להוסיף את הערך ; charset=utf-8.
  • אופציונלי: Authorization: Bearer <token>
    • אסימון מזהה משתמש מסוג Firebase Authentication של המשתמש המקושר שמגיש את הבקשה. הקצה העורפי מאמת את האסימון הזה באופן אוטומטי ועושה אותו זמין ב-context של ה-handler. אם האסימון לא תקף, הבקשה תידחה.
  • אופציונלי: Firebase-Instance-ID-Token: <iid>
    • אסימון ההרשמה ל-FCM מ-SDK של לקוח Firebase. הערך חייב להיות מחרוזת. הוא זמין ב-context של הטיפול. הוא משמש לטירגוט של התראות שנשלחות מהאפליקציה.
  • אופציונלי: X-Firebase-AppCheck: <token>
    • האסימון של Firebase App Check שסופק על ידי אפליקציית הלקוח ששולחת את הבקשה. הקצה העורפי מאמת את האסימון הזה באופן אוטומטי ומפענח אותו, ומחדיר את appId ל-context של הטיפול. אם לא ניתן לאמת את האסימון, הבקשה נדחית. (זמין ל-SDK בגרסה 3.14.0 ואילך)

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

הערה: בלקוחות JavaScript, הבקשות האלה מפעילות בדיקת קדם OPTIONS של CORS, כי:

  • לא ניתן להפר את המדיניות: application/json הערך חייב להיות text/plain או application/x-www-form-urlencoded.
  • הכותרת Authorization היא לא כותרת בקשה ברשימת ההיתרים של CORS.
  • אסור להשתמש בכותרות אחרות באופן דומה.

הטריגר שניתן לקריאה מטפל באופן אוטומטי בבקשות ה-OPTIONS האלה.

גוף הבקשה

גוף בקשת ה-HTTP צריך להיות אובייקט JSON עם אחד מהשדות הבאים:

  • חובה: data – הארגומנט המועבר לפונקציה. זה יכול להיות כל ערך JSON חוקי. הנתונים מקודדים באופן אוטומטי לסוגי JavaScript מקומיים בהתאם לפורמט הסריאליזציה שמתואר בהמשך.

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

פורמט התגובה: קודי סטטוס

יש כמה מקרים שיכולים לגרום לקודי סטטוס HTTP שונים ולקודי סטטוס מחרוזת שונים של שגיאות בתגובה.

  1. במקרה של שגיאת HTTP לפני ההפעלה של הטריגר client, התגובה לא מטופלת כפונקציית לקוח. לדוגמה, אם לקוח מנסה להפעיל פונקציה שלא קיימת, הוא מקבל תגובה מסוג 404 Not Found.

  2. אם הטריגר של הלקוח הופעל אבל הבקשה בפורמט שגוי, למשל היא לא בפורמט JSON, יש בה שדות לא חוקיים או שהשדה data חסר, הבקשה תידחה עם 400 Bad Request וקוד השגיאה INVALID_ARGUMENT.

  3. אם אסימון האימות שסופק בבקשה לא תקף, הבקשה תידחה עם 401 Unauthorized, עם קוד השגיאה UNAUTHENTICATED.

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

  5. אם הטריגר הניתן לקריאה הופעל, אבל נכשל עם חריגה שלא טופלה או החזיר הבטחה שנכשלה, הבקשה תידחה עם 500 Internal Server Error, עם קוד השגיאה INTERNAL. כך אפשר למנוע חשיפת שגיאות קוד בטעות למשתמשי הקצה.

  6. אם הפונקציה הניתנת לקריאה מופעלת ומחזירה תנאי שגיאה מפורש באמצעות ה-API שסופק לפונקציות ניתנות לקריאה, הבקשה נכשלת. קוד הסטטוס של ה-HTTP שמוחזר מבוסס על המיפוי הרשמי של סטטוס השגיאה לסטטוס HTTP, כפי שהוא מוגדר ב-code.proto. קוד השגיאה הספציפי, ההודעה והפרטים שמוחזרים מקודדים בגוף התגובה, כפי שמפורט בהמשך. כלומר, אם הפונקציה מחזירה שגיאה מפורשת עם סטטוס OK, לסטטוס התגובה יהיה הערך 200 OK, אבל השדה error יוגדר בתגובה.

  7. אם הטריגר של הלקוח מצליח, סטטוס התגובה הוא 200 OK.

פורמט התגובה: כותרות

התגובה כוללת את הכותרות הבאות:

  • Content-Type: application/json
  • אפשר להוסיף את הערך ; charset=utf-8.

גוף התשובה

התגובה מנקודת קצה של לקוח היא תמיד אובייקט JSON. הוא מכיל לפחות את השדה result או error, יחד עם שדות אופציונליים. אם התגובה היא לא אובייקט JSON או שהיא לא מכילה את הערכים data או error, ה-SDK של הלקוח צריך להתייחס לבקשה ככישלון עם קוד השגיאה של Google‏ INTERNAL (13).

  • error – אם השדה הזה קיים, הבקשה נחשבת ככשלה, ללא קשר לקוד הסטטוס של HTTP או אם השדה data קיים גם כן. הערך בשדה הזה צריך להיות אובייקט JSON בפורמט הסטנדרטי של Google Cloud HTTP Mapping לשגיאות, עם שדות ל-status, ל-message ול-details (אופציונלי). השדה code לא ייכלל. אם השדה status לא מוגדר או שהוא מכיל ערך לא חוקי, הלקוח צריך להתייחס לסטטוס כ-INTERNAL, בהתאם ל-code.proto. אם השדה details קיים, הוא נכלל בכל פרטי המשתמש שמצורפים לשגיאה ב-SDK של הלקוח, אם רלוונטי.
    הערה: השדה details כאן הוא ערך שמסופק על ידי המשתמש. היא לא חייבת להיות רשימה של ערכים שמקושרים לפי סוג אב, כמו בפורמט Status של Google.
  • result – הערך שהפונקציה מחזירה. זה יכול להיות כל ערך JSON חוקי. ה-SDK של firebase-functions מקודד באופן אוטומטי את הערך שהמשתמש מחזיר לפורמט JSON הזה. ערכות ה-SDK של הלקוח מפענחות את הפרמטרים האלה באופן אוטומטי לסוגים מקומיים בהתאם לפורמט הסריאליזציה שמתואר בהמשך.

אם יש שדות אחרים, המערכת תתעלם מהם.

סריאליזציה

פורמט הסריאליזציה של עומסי נתונים שרירותיים זהה גם לבקשה וגם לתגובה.

כדי לשמור על עקביות בפלטפורמה, הם מקודדים ב-JSON כאילו הם הערך של השדה Any במאגר פרוטוקול proto3, באמצעות מיפוי JSON סטנדרטי. ערכים של סוגים פשוטים כמו null,‏ int,‏ double או string מקודדים ישירות ולא כוללים את הסוג המפורש שלהם. לכן, float ו-double מקודדים באותו אופן, ויכול להיות שלא תדעו איזה מהם התקבל בצד השני של השיחה. לסוגי נתונים שלא מוגדרים ב-JSON באופן מקורי, נעשה שימוש בקידוד proto3 עם סוג עבור הערך. מידע נוסף זמין במסמכי העזרה בנושא Any JSON encoding.

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

  • null – null
  • int (signed או unsigned, עד 32 ביט) – לדוגמה, 3 או -30.
  • float – לדוגמה, 3.14
  • כפול – לדוגמה, 3.14
  • boolean – true או false
  • מחרוזת – לדוגמה, "hello world"
  • map<string, any=""> – לדוגמה, {"x": 3}</string,>
  • list – לדוגמה, [1, 2, 3]
  • long (signed או unsigned, עד 64 ביט) – [פרטים נוספים מופיעים בהמשך]

אין תמיכה בערכים NaN ו-Infinity עבור float ו-double.

הערה: long הוא סוג מיוחד שלא מותר בדרך כלל ב-JSON, אבל הוא נכלל במפרט של proto3. לדוגמה, הם מקודדים כך:

long

{
    '@type': 'type.googleapis.com/google.protobuf.Int64Value',
    'value': '-123456789123456'
}

unsigned long

{
    '@type': 'type.googleapis.com/google.protobuf.UInt64Value',
    'value': '123456789123456'
}

באופן כללי, צריך להתייחס למפתח @type כמפתח ששמור לשימוש פנימי, ולא להשתמש בו למפות שמועברות.

מאחר שהסוג לא מצוין לסוגי נתונים פשוטים, ערכים מסוימים ישנו את הסוג שלהם אחרי שהם יועברו דרך החיבור. float שהוענק הופך ל-double. short הופך ל-int וכן הלאה. ב-Android יש תמיכה גם ב-List וגם ב-JSONArray לערכים של רשימות. במקרים כאלה, העברה של JSONArray תניב List.

אם מתבצעת סריקה חוזרת של מפה עם שדה @type לא ידוע, היא נשארת כמפה. כך המפתחים יכולים להוסיף שדות עם סוגים חדשים לערכי ההחזרה שלהם בלי לשבור לקוחות ישנים יותר.

דוגמאות קוד

הדוגמאות בקטע הזה ממחישות איך לקודד את הנתונים הבאים:

  • דוגמה ל-callable.call ב-Swift
  • תגובה של אישור לשיחה
  • תגובה של כשל לשיחה

דוגמה ל-Callable.call ב-Swift לקידוד

callable.call([
    "aString": "some string",
    "anInt": 57,
    "aFloat": 1.23,
    "aLong": -123456789123456 as Int64
])

כותרת הבקשה:

Method: POST
Content-Type: application/json; charset=utf-8
Authorization: Bearer some-auth-token
Firebase-Instance-ID-Token: some-iid-token

גוף הבקשה:

{
    "data": {
        "aString": "some string",
        "anInt": 57,
        "aFloat": 1.23,
        "aLong": {
            "@type": "type.googleapis.com/google.protobuf.Int64Value",
            "value": "-123456789123456"
        }
    }
}

תגובה לקידוד

return {
    "aString": "some string",
    "anInt": 57,
    "aFloat": 1.23
};

כותרת תגובה מוצלחת:

200 OK
Content-Type: application/json; charset=utf-8

גוף התגובה במקרה של הצלחה:

{
    "response": {
        "aString": "some string",
        "anInt": 57,
        "aFloat": 1.23
    }
}

תגובה של כישלון בקידוד

throw new HttpsError("unauthenticated", "Request had invalid credentials.", {
  "some-key": "some-value"
});

כותרת התגובה שנכשלה:

401 UNAUTHENTICATED
Content-Type: application/json; charset=utf-8

גוף התשובה שנכשלה:

{
    "error": {
        "message": "Request had invalid credentials.",
        "status": "UNAUTHENTICATED",
        "details": {
            "some-key": "some-value"
        }
    }
}