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

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

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

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

  • จำเป็น: Content-Type: application/json
    • ทางเลือก ; charset=utf-8 อนุญาตให้ใช้ ; charset=utf-8
  • ทางเลือก: Authorization: Bearer <token>
    • โทเค็นรหัสผู้ใช้ Firebase Authentication สำหรับผู้ใช้ที่เข้าสู่ระบบซึ่งส่งคำขอ แบ็กเอนด์ จะตรวจสอบ โทเค็นนี้โดยอัตโนมัติและทำให้พร้อมใช้งานใน 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 preflight เนื่องจาก:

ทริกเกอร์ที่เรียกได้จะจัดการคำขอ 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 ที่ถูกต้องก็ได้ SDK ฟังก์ชัน firebase จะเข้ารหัสค่าที่ผู้ใช้ส่งคืนเป็นรูปแบบ 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"
        }
    }
}