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

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

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

يجب أن يكون طلب 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>
    • الرمز المميّز الذي توفّره ميزة &quot;فحص التطبيقات من Firebase&quot; لتطبيق العميل الذي يرسل الطلب. تتحقّق الخلفية تلقائيًا من هذا الرمز المميز وتفك تشفيره، وتُدرِج appId في context للمعالج. وفي حال تعذّر إثبات صحة الرمز المميّز، يتم رفض الطلب. (متوفّر للإصدار 3.14.0 من حزمة تطوير البرامج (SDK) أو الإصدارات الأحدث)

إذا تم تضمين أي عناوين أخرى، سيتم رفض الطلب، كما هو موضّح في مستندات الرد أدناه.

ملاحظة: في برامج 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 المقدَّم في الطلب غير صالح، يكون السلوك غير محدّد. لا يتم التحقّق من الرمز المميّز في كل طلب، باستثناء الحالات التي يتم فيها استخدامه لإرسال إشعار فوري باستخدام ميزة "المراسلة عبر السحابة الإلكترونية من 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، يجب أن يتعامل حزمة تطوير البرامج (SDK) الخاصة بالعميل مع الطلب على أنّه تعذّر تنفيذه مع رمز خطأ 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
  • عدد صحيح (موقّع أو غير موقّع، يصل إلى 32 بت)، مثل 3 أو -30
  • float - e.g. 3.14
  • مضاعفة - مثال: 3.14
  • قيمة منطقية - true أو false
  • سلسلة - على سبيل المثال "hello world"
  • map<string, any=""> - e.g. {"x": 3}</string,>
  • القائمة - مثال: [1, 2, 3]
  • long (signed or unsigned, up to 64 bits) - [see below for details]

لا تتوفّر قيم 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"
        }
    }
}