ข้อกำหนดโปรโตคอลสำหรับ https.onCall

ทริกเกอร์ https.onCall สำหรับ Cloud Functions คือทริกเกอร์ HTTPS ที่มีรูปแบบเฉพาะสำหรับคำขอและการตอบกลับ ส่วนนี้จะระบุรูปแบบคำขอและการตอบกลับ HTTPS ที่ SDK ของไคลเอ็นต์ใช้เพื่อติดตั้งใช้งาน API ข้อมูลนี้อาจเป็นประโยชน์หากคุณไม่สามารถใช้ SDK ของ Android, แพลตฟอร์ม Apple หรือเว็บ SDK เพื่อตอบสนองความต้องการได้

รูปแบบคำขอ: ส่วนหัว

คำขอ HTTP ไปยังปลายทางทริกเกอร์ที่เรียกใช้ได้ต้องเป็น POST ที่มีส่วนหัวต่อไปนี้

  • บังคับ: Content-Type: application/json
    • อนุญาตให้ใช้ ; charset=utf-8 ซึ่งเป็นตัวเลือก
  • ตัวเลือก: Authorization: Bearer <token>
  • ตัวเลือก: 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. หากมีการเรียกใช้ทริกเกอร์ที่เรียกใช้ได้ แต่ล้มเหลวเนื่องจากข้อยกเว้นที่ไม่ได้จัดการหรือแสดงผล Promise ที่ล้มเหลว ระบบจะปฏิเสธคำขอด้วย 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 อย่างน้อย 1 รายการ พร้อมกับช่องที่ไม่บังคับ หากการตอบกลับไม่ใช่ออบเจ็กต์ JSON หรือไม่มี data หรือ error SDK ของไคลเอ็นต์ควรถือว่าคำขอไม่สำเร็จโดยมีรหัสข้อผิดพลาดของ Google คือ INTERNAL (13)

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

หากมีช่องอื่นๆ อยู่ ระบบควรละเว้นช่องเหล่านั้น

การซีเรียลไลซ์

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

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

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

  • null - null
  • int (มีหรือไม่มีเครื่องหมาย สูงสุด 32 บิต) - เช่น 3 หรือ -30
  • float - เช่น 3.14
  • double - เช่น 3.14
  • boolean - true หรือ false
  • string - เช่น "hello world"
  • map<string, any=""> - เช่น {"x": 3}</string,>
  • list - เช่น [1, 2, 3]
  • long (มีหรือไม่มีเครื่องหมาย สูงสุด 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"
        }
    }
}