مواصفات البروتوكول لـ https.onCall

مشغّل https.onCall في Cloud Functions هو مشغّل HTTPS بتنسيق محدّد للطلب والاستجابة. يوفّر هذا القسم مواصفات لتنسيقات طلب HTTPS واستجابته التي تستخدمها حِزم تطوير البرامج (SDK) للعملاء لتنفيذ واجهة برمجة التطبيقات. قد تكون هذه المعلومات مفيدة لك إذا تعذّر تلبية متطلباتك باستخدام منصات Android أو Apple أو حِزم SDK للويب.

تنسيق الطلب: العناوين

يجب أن يكون طلب HTTP المُرسَل إلى نقطة نهاية مشغّل قابل للاستدعاء من النوع POST مع الرؤوس التالية:

  • مطلوبة: Content-Type: application/json
    • يُسمح باستخدام ; charset=utf-8 اختياري.
  • اختياري: Authorization: Bearer <token>
    • رمز تعريف Firebase Authentication للمستخدِم الذي سجّل الدخول ويقدّم الطلب تحقّق الخلفية تلقائيًا من هذا الرمز المميّز وتوفّره في context للمعالج. إذا لم يكن الرمز المميّز صالحًا، يتم رفض الطلب.
  • اختياري: Firebase-Instance-ID-Token: <iid>
    • رمز تسجيل "المراسلة عبر السحابة الإلكترونية من Firebase" من حزمة تطوير البرامج (SDK) لعميل Firebase يجب أن تكون هذه القيمة سلسلة. تتوفّر هذه الميزة في context للاسم المعرِّف. ويُستخدَم لاستهداف الإشعارات الفورية.
  • اختياري: X-Firebase-AppCheck: <token>
    • رمز مفتاح أمان فحص التطبيقات من Firebase الذي يوفّره تطبيق العميل الذي يُجري الطلب. تتحقّق الخلفية تلقائيًا من هذا الرمز المميّز وتُفكّ تشفيره، ويُحقّق المعالج من appId في context. إذا تعذّر verifying التحقّق من الرمز المميّز، يتم رفض الطلب. (تتوفّر هذه الميزة لحِزم 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 المقدَّم في الطلب غير صالح، يكون السلوك غير محدّد. لا يتم التحقّق من الرمز المميّز في كل طلب، إلا عند استخدامه لإرسال إشعار فوري باستخدام ميزة "المراسلة من خلال السحابة الإلكترونية من Firebase".

  5. إذا تمّ استدعاء عامل التشغيل القابل للاستدعاء، ولكن تعذّر إكماله بسبب استثناء لم تتم معالجته أو إذا تمّ إرجاع وعد تعذّر إكماله، يتم رفض الطلب باستخدام 500 Internal Server Error مع رمز الخطأ INTERNAL. ويمنع ذلك ظهور أخطاء الترميز للمستخدمين النهائيين عن طريق الخطأ.

  6. إذا تمّ استدعاء الدالة القابلة للاستدعاء وعرض حالة خطأ صريحة باستخدام واجهة برمجة التطبيقات المقدَّمة للدوالّ القابلة للاستدعاء، تعذّر تنفيذ الطلب. يستند رمز حالة HTTP الذي يتم إرجاعه إلى التعيين الرسمي لحالة الخطأ إلى حالة HTTP، كما هو محدّد في code.proto. يتم ترميز رمز الخطأ والرسالة والتفاصيل المحدّدة التي يتم عرضها في نص الاستجابة كما هو موضّح أدناه. وهذا يعني أنّه إذا كانت الدالة تعرِض خطأ صريحًا بحالة OK، تكون حالة الاستجابة 200 OK، ولكن يتم ضبط الحقل error في الاستجابة.

  7. إذا كان عامل تشغيل العميل ناجحًا، تكون حالة الاستجابة هي 200 OK.

تنسيق الاستجابة: العناوين

تحتوي الاستجابة على العناوين التالية:

  • Content-Type: application/json
  • يُسمح باستخدام ; charset=utf-8 اختياري.

نص الاستجابة

يكون الردّ من نقطة نهاية العميل دائمًا عنصرًا في تنسيق JSON. أن تحتوي على result أو error على الأقل، بالإضافة إلى أي حقول اختيارية إذا لم يكن الردّ عنصرًا بتنسيق JSON أو لم يحتوي على data أو error، يجب أن يتعامل IDE للعميل مع الطلب على أنّه تعذّر برمز الخطأ INTERNAL (13) من Google.

  • error: في حال توفّر هذا الحقل، يُعتبر الطلب تعذّر بغض النظر عن رمز حالة HTTP أو ما إذا كان الحقل data متوفّرًا أيضًا. يجب أن تكون قيمة هذا الحقل عنصرًا بتنسيق JSON في تنسيق ربط HTTP في Google Cloud العادي للأخطاء، مع حقول status وmessage و (اختياريًا) details. يجب عدم تضمين الحقل code. إذا لم يتم ضبط حقل status أو كانت قيمته غير صالحة، يجب أن يتعامل العميل مع الحالة على أنّها INTERNAL، وفقًا لمعيار code.proto. إذا كان details متوفّرًا، يتم تضمينه في أي معلومات مستخدم مرفقة بالخطأ في حزمة تطوير البرامج (SDK) للعميل، إن أمكن.
    ملاحظة: حقل details هنا هو قيمة يقدّمها المستخدم. ولا يُشترَط أن تكون قائمة بالقيم مفعَّلة حسب النموذج الأولي كما هو الحال في تنسيق Status من Google.
  • result: القيمة التي تعرضها الدالة يمكن أن تكون هذه القيمة أي قيمة صالحة لملف JSON. تُشفِّر حزمة تطوير البرامج (SDK) لـ firebase-functions تلقائيًا القيمة التي يعرضها المستخدم بتنسيق JSON هذا. تعمل حِزم تطوير البرامج (SDK) للعملاء على فك ترميز هذه المَعلمات تلقائيًا إلى أنواع أساسية وفقًا لتنسيق التسلسل الموضّح أدناه.

في حال توفّر حقول أخرى، يجب تجاهلها.

التسلسل

يكون تنسيق التسلسل لحمولات البيانات العشوائية هو نفسه لكل من الطلب والاستجابة.

وللحفاظ على اتساق المنصة، يتم ترميز هذه القيم بتنسيق JSON كما لو كانت قيمة حقل Any في ملف تخزين بروتوكول proto3، وذلك باستخدام تعيين JSON العادي. يتم ترميز قيم الأنواع البسيطة، مثل null أو int أو double أو string مباشرةً، ولا تتضمّن نوعها الصريح. وبالتالي، يتم ترميز float وdouble بالطريقة نفسها، وقد لا تعرف أيهما يتم تلقيه في الطرف الآخر من المكالمة. بالنسبة إلى الأنواع غير الأصلية في JSON، يتم استخدام ترميز proto3 من النوع المكتوب للقيمة. لمزيد من المعلومات، اطّلِع على مستندات ترميز Any JSON.

يُسمح بالأنواع التالية:

  • null - null
  • int (موقَّت أو غير موقَّت، بسعة تصل إلى 32 بت) - مثل 3 أو -30
  • رمز متحرك - على سبيل المثال 3.14
  • مزدوج، مثل 3.14
  • قيمة منطقية: true أو false
  • سلسلة - على سبيل المثال "hello world"
  • map<string, any=""> - على سبيل المثال، {"x": 3}</string,>
  • قائمة - على سبيل المثال [1, 2, 3]
  • long (موقَّعة أو غير موقَّعة، حتى 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"
        }
    }
}