ข้อกำหนดโปรโตคอลสำหรับ 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 ของตัวแฮนเดิล หากโทเค็นไม่ถูกต้อง ระบบจะปฏิเสธคำขอ
  • ไม่บังคับ: Firebase-Instance-ID-Token: <iid>
    • โทเค็นการลงทะเบียน FCM จาก Firebase Client SDK ต้องเป็นสตริง โดยมีอยู่ใน context ของตัวแฮนเดิล ซึ่งใช้เพื่อกําหนดเป้าหมายข้อความ Push
  • ไม่บังคับ: X-Firebase-AppCheck: <token>
    • โทเค็น Firebase App Check ที่ระบุโดยแอปไคลเอ็นต์ที่ส่งคำขอ แบ็กเอนด์จะยืนยันและถอดรหัสโทเค็นนี้โดยอัตโนมัติ โดยแทรก appId ใน context ของตัวแฮนเดิล หากยืนยันโทเค็นไม่ได้ คำขอจะถูกปฏิเสธ (ใช้ได้กับ SDK ที่ใช้เวอร์ชันตั้งแต่ 3.14.0 ขึ้นไป)

หากมีการใช้ส่วนหัวอื่นๆ ระบบจะปฏิเสธคําขอตามที่อธิบายไว้ในเอกสารการตอบกลับด้านล่าง

หมายเหตุ: ในไคลเอ็นต์ JavaScript คำขอเหล่านี้จะทริกเกอร์การตรวจสอบ CORS OPTIONS ล่วงหน้าเนื่องจากสาเหตุต่อไปนี้

ทริกเกอร์ที่เรียกใช้ได้จะจัดการคําขอ 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 ของไคลเอ็นต์ควรถือว่าคําขอไม่สําเร็จพร้อมรหัสข้อผิดพลาด INTERNAL (13) ของ Google

  • error - หากมีช่องนี้ ระบบจะถือว่าคําขอไม่สําเร็จ ไม่ว่ารหัสสถานะ HTTP จะเป็นอะไรหรือมี data ด้วยหรือไม่ก็ตาม ค่าของฟิลด์นี้ควรเป็นออบเจ็กต์ JSON ในรูปแบบ การแมป HTTP ของ Google Cloud มาตรฐานสำหรับข้อผิดพลาด โดยมีช่องสำหรับ status, message และ (ไม่บังคับ) details โดยไม่รวมฟิลด์ code หากไม่ได้ตั้งค่าช่อง status หรือเป็นค่าที่ไม่ถูกต้อง ไคลเอ็นต์ควรถือว่าสถานะเป็น INTERNAL ตาม code.proto หากมี details อยู่ details จะรวมอยู่ในข้อมูลผู้ใช้ที่แนบมากับข้อผิดพลาดใน SDK ของไคลเอ็นต์ (หากมี)
    หมายเหตุ: ช่อง details ที่นี่คือค่าที่ผู้ใช้ระบุ โดยไม่จำเป็นต้องเป็นรายการค่าที่คีย์ตามโปรโตไทป์เหมือนในรูปแบบ Status ของ Google
  • result - ค่าที่ฟังก์ชันแสดงผล ซึ่งอาจเป็นค่า JSON ที่ถูกต้องรายการใดก็ได้ firebase-functions SDK จะเข้ารหัสค่าที่ผู้ใช้แสดงผลเป็นรูปแบบ JSON นี้โดยอัตโนมัติ SDK ของไคลเอ็นต์จะถอดรหัสพารามิเตอร์เหล่านี้เป็นประเภทเนทีฟโดยอัตโนมัติตามรูปแบบการจัดเก็บตามที่อธิบายไว้ด้านล่าง

หากมีช่องอื่นๆ อยู่ ระบบจะไม่สนใจช่องเหล่านั้น

การจัดรูปแบบข้อมูล

รูปแบบการจัดรูปแบบข้อมูลสำหรับเพย์โหลดข้อมูลแบบกำหนดเองจะเหมือนกันทั้งสำหรับคำขอและการตอบกลับ

ข้อมูลเหล่านี้ได้รับการเข้ารหัสเป็น JSON โดยใช้การแมป JSON มาตรฐาน ราวกับว่าเป็นค่าของช่อง Any ในบัฟเฟอร์โปรโตคอล proto3 เพื่อให้แพลตฟอร์มมีความสอดคล้องกัน ค่าของประเภทพื้นฐาน เช่น null, int, double หรือ string จะเข้ารหัสโดยตรงและไม่มีประเภทที่ชัดเจน ดังนั้น float และ double จะได้รับการเข้ารหัสด้วยวิธีเดียวกัน และคุณอาจไม่ทราบว่าระบบจะได้รับรหัสใดเมื่อสิ้นสุดการโทร สําหรับประเภทที่ไม่ใช่ JSON จะใช้การเข้ารหัส proto3 ที่มีประเภทสําหรับค่า โปรดดูข้อมูลเพิ่มเติมในเอกสารประกอบเกี่ยวกับการเข้ารหัส JSON แบบใดก็ได้

โดยอนุญาตให้ใช้ประเภทต่อไปนี้

  • null - null
  • int (signed or unsigned, up to 32 bit) - เช่น 3 หรือ -30
  • ตัวเลขทศนิยม เช่น 3.14
  • คู่ - เช่น 3.14
  • บูลีน - true หรือ false
  • สตริง เช่น "hello world"
  • แผนที่<string, any=""> - เช่น {"x": 3}</string,>
  • list - เช่น [1, 2, 3]
  • long (signed or unsigned, up to 64 bits) - [see below for details]

ระบบไม่รองรับค่า NaN และ Infinity สำหรับ float และ double

โปรดทราบว่า long เป็นประเภทพิเศษที่ปกติแล้วไม่อนุญาตใน JSON แต่อยู่ในข้อกำหนดของ proto3 ตัวอย่างเช่น ระบบจะเข้ารหัสข้อมูลเหล่านี้ดังนี้

ยาว

{
    '@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"
        }
    }
}