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

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

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

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

  • จำเป็น: Content-Type: application/json
    • ตัวเลือก ; charset=utf-8 อนุญาตให้ใช้ ; charset=utf-8
  • ทางเลือก: Authorization: Bearer <token>
    • โทเค็น ID ผู้ใช้การตรวจสอบความถูกต้องของ Firebase สำหรับผู้ใช้ที่เข้าสู่ระบบซึ่งส่งคำขอ แบ็กเอนด์ จะตรวจสอบ โทเค็นนี้โดยอัตโนมัติและทำให้พร้อมใช้งานใน context ของตัวจัดการ หากโทเค็นไม่ถูกต้อง คำขอจะถูกปฏิเสธ
  • ทางเลือก: Firebase-Instance-ID-Token: <iid>
    • โทเค็นการลงทะเบียน FCM จาก SDK ไคลเอนต์ Firebase นี่ต้องเป็นสตริง สิ่งนี้มีอยู่ใน context ของตัวจัดการ ใช้สำหรับการกำหนดเป้าหมายการแจ้งเตือนแบบพุช
  • ทางเลือก: 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 ที่ระบุในคำขอไม่ถูกต้อง ลักษณะการทำงานนั้นไม่ได้ถูกกำหนด โทเค็นจะไม่ถูกตรวจสอบในทุกคำขอ ยกเว้นเมื่อมีการใช้เพื่อส่งการแจ้งเตือนแบบพุชด้วย 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 อนุญาตให้ใช้ ; 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 ที่ถูกต้องก็ได้ Firebase-functions SDK จะเข้ารหัสค่าที่ผู้ใช้ส่งคืนในรูปแบบ JSON นี้โดยอัตโนมัติ SDK ของไคลเอ็นต์จะถอดรหัสพารามิเตอร์เหล่านี้โดยอัตโนมัติเป็นประเภทเนทีฟตามรูปแบบการทำให้เป็นอนุกรมที่อธิบายไว้ด้านล่าง

หากมีฟิลด์อื่นอยู่ ควรละเว้น

การทำให้เป็นอนุกรม

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

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

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

  • โมฆะ - null
  • int (ลงนามหรือไม่ได้ลงนาม สูงสุด 32 บิต) - เช่น 3 หรือ -30
  • ลอย - เช่น 3.14
  • สองเท่า - เช่น 3.14
  • บูลีน - true หรือ false
  • สตริง - เช่น "hello world"
  • แผนที่ - เช่น {"x": 3}
  • รายการ - เช่น [1, 2, 3]
  • ยาว (ลงนามหรือไม่ลงนาม สูงสุด 64 บิต) - [ดูรายละเอียดด้านล่าง]

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

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

ยาว

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

ไม่ได้ลงนามยาว

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