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

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

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

คำขอ 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 คำขอเหล่านี้จะทริกเกอร์OPTIONSคำขอเบื้องต้นของ 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. หากมีการเรียกใช้ทริกเกอร์ที่เรียกใช้ได้ แต่ไม่สำเร็จเนื่องจากมีข้อยกเว้นที่ไม่ได้จัดการหรือส่งคืน 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 พร้อมกับฟิลด์ที่ไม่บังคับ หากการตอบกลับไม่ใช่ออบเจ็กต์ 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 ที่นี่คือค่าที่ผู้ใช้ระบุ ไม่จำเป็นต้องเป็นรายการค่าที่คีย์ตามประเภท Proto เหมือนในรูปแบบของ Google Status
  • result - ค่าที่ฟังก์ชันแสดงผล ซึ่งอาจเป็นค่า JSON ที่ถูกต้องก็ได้ Firebase Functions SDK จะเข้ารหัสค่าที่ผู้ใช้ส่งคืนเป็นรูปแบบ JSON นี้โดยอัตโนมัติ SDK ของไคลเอ็นต์จะถอดรหัสพารามิเตอร์เหล่านี้เป็นประเภทดั้งเดิมโดยอัตโนมัติตามรูปแบบการซีเรียลไลซ์ที่อธิบายไว้ด้านล่าง

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

การเรียงอันดับ

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

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

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

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

ไม่รองรับค่า 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"
        }
    }
}