البدء: كتابة الدوال الأولى واختبارها ونشرها


لبدء استخدام Cloud Functions، جرِّب تنفيذ هذا البرنامج التعليمي الذي يبدأ بمهام الإعداد المطلوبة ثم ينتقل إلى إنشاء وظيفتَين مرتبطتَين واختبارهما ونشرهما:

  • دالة "إضافة رسالة" تعرض عنوان URL يقبل قيمة نصية ويكتبها في Cloud Firestore.
  • دالة "تحويل إلى أحرف كبيرة" يتم تشغيلها عند Cloud Firestore الكتابة وتحويل النص إلى أحرف كبيرة

لقد اخترنا Cloud Firestore ووظائف JavaScript التي يتم تشغيلها عبر HTTP لهذا النموذج، لأنّه يمكن اختبار مشغّلات الخلفية هذه بشكل كامل من خلال Firebase Local Emulator Suite. تتيح مجموعة الأدوات هذه أيضًا استخدام Realtime Database وPubSub وAuth ومشغّلات HTTP القابلة للاستدعاء. يمكن اختبار الأنواع الأخرى من المشغّلات التي تعمل في الخلفية، مثل Remote Config وTestLab ومشغّلات "إحصاءات Google"، بشكل تفاعلي باستخدام مجموعات أدوات غير موضّحة في هذه الصفحة.

توضّح الأقسام التالية من هذا البرنامج التعليمي الخطوات المطلوبة لإنشاء النموذج واختباره ونشره. إذا كنت تفضّل تشغيل الرمز وفحصه فقط، انتقِل إلى مراجعة نموذج الرمز الكامل.

إنشاء مشروع على Firebase

  1. في Firebase وحدة التحكّم، انقر على إضافة مشروع.

    • لإضافة موارد Firebase إلى مشروع حالي، أدخِل اسم المشروع أو اختَره من القائمة المنسدلة.Google Cloud

    • لإنشاء مشروع جديد، أدخِل اسم مشروع. يمكنك أيضًا تعديل رقم تعريف المشروع المعروض أسفل اسم المشروع.

  2. راجِع بنود Firebase واقبلها إذا طُلب منك ذلك.

  3. انقر على متابعة.

  4. (اختياري) يمكنك إعداد Google Analytics لمشروعك، ما يتيح تجربة مثالية باستخدام منتجات Firebase التالية: Firebase A/B Testing وCloud Messaging وCrashlytics وIn-App Messaging وRemote Config (بما في ذلك التخصيص).

    اختَر حسابًا حاليًا Google Analytics أو أنشِئ حسابًا جديدًا. في حال إنشاء حساب جديد، اختَر Analytics الموقع الجغرافي لإعداد التقارير، ثم اقبل إعدادات مشاركة البيانات وبنود Google Analytics مشروعك.

  5. انقر على إنشاء مشروع (أو إضافة Firebase، إذا كنت تضيف Firebase إلى مشروع Google Cloud حالي).

توفّر Firebase تلقائيًا موارد لمشروعك على Firebase. عند اكتمال العملية، سيتم نقلك إلى صفحة النظرة العامة لمشروعك على Firebase في وحدة تحكّم Firebase.

إعداد Node.js وFirebase CLI

ستحتاج إلى بيئة Node.js لكتابة الدوال، وستحتاج إلى واجهة سطر الأوامر Firebase لنشر الدوال في وقت التشغيل Cloud Functions. لتثبيت Node.js وnpm، ننصحك باستخدام Node Version Manager.

بعد تثبيت Node.js وnpm، ثبِّت واجهة سطر الأوامر Firebase باستخدام الطريقة التي تفضّلها. لتثبيت واجهة سطر الأوامر من خلال npm، استخدِم الأمر التالي:

npm install -g firebase-tools

يؤدي ذلك إلى تثبيت أمر firebase المتاح على مستوى العالم. إذا تعذّر تنفيذ الأمر، قد تحتاج إلى تغيير أذونات npm. للتحديث إلى أحدث إصدار من firebase-tools، أعِد تنفيذ الأمر نفسه.

تهيئة مشروعك

عند إعداد حزمة تطوير البرامج (SDK) الخاصة بـ Firebase في Cloud Functions، يمكنك إنشاء مشروع فارغ يحتوي على التبعيات وبعض نماذج الرموز البرمجية البسيطة، ويمكنك اختيار TypeScript أو JavaScript لإنشاء الدوال. لأغراض هذا البرنامج التعليمي، عليك أيضًا تهيئة Cloud Firestore.

لبدء مشروعك، اتّبِع الخطوات التالية:

  1. نفِّذ الأمر firebase login لتسجيل الدخول عبر المتصفح والمصادقة على واجهة سطر الأوامر Firebase.

  2. انتقِل إلى دليل مشروعك على Firebase.

  3. نفِّذ الأمر firebase init firestore. في هذا البرنامج التعليمي، يمكنك قبول القيم التلقائية عند مطالبتك بقواعد Firestore وملفات الفهرس. إذا لم يسبق لك استخدام Cloud Firestore في هذا المشروع، عليك أيضًا اختيار وضع وموقع جغرافي لبدء استخدام Firestore كما هو موضّح في بدء استخدام Cloud Firestore.

  4. نفِّذ الأمر firebase init functions. سيطلب منك واجهة سطر الأوامر اختيار قاعدة رموز برمجية حالية أو إنشاء قاعدة رموز برمجية جديدة وتسميتها. عندما تكون في بداية استخدامك، سيكون رمز أساسي واحد في الموقع التلقائي كافيًا، ولكن مع توسّع عملية التنفيذ، قد تحتاج إلى تنظيم الدوال في رموز أساسية.

  5. تمنحك واجهة سطر الأوامر الخيارات التالية لدعم اللغة:

    في هذا البرنامج التعليمي، اختَر JavaScript.

  6. توفّر لك واجهة سطر الأوامر خيارًا لتثبيت التبعيات باستخدام npm. يمكنك رفض ذلك إذا أردت إدارة التبعيات بطريقة أخرى، ولكن في حال الرفض، عليك تنفيذ الأمر npm install قبل محاكاة وظائفك أو نشرها.

بعد اكتمال هذه الأوامر بنجاح، سيظهر هيكل مشروعك على النحو التالي:

myproject
 +- .firebaserc    # Hidden file that helps you quickly switch between
 |                 # projects with `firebase use`
 |
 +- firebase.json  # Describes properties for your project
 |
 +- functions/     # Directory containing all your functions code
      |
      +- .eslintrc.json  # Optional file containing rules for JavaScript linting.
      |
      +- package.json  # npm package file describing your Cloud Functions code
      |
      +- index.js      # main source file for your Cloud Functions code
      |
      +- node_modules/ # directory where your dependencies (declared in
                       # package.json) are installed

يحتوي ملف package.json الذي تم إنشاؤه أثناء عملية الإعداد على مفتاح مهم هو "engines": {"node": "16"}. يحدّد هذا الخيار إصدار Node.js الذي ستستخدمه لكتابة الدوال ونشرها. يمكنك اختيار إصدارات أخرى متوافقة.

استيراد الوحدات المطلوبة وتهيئة تطبيق

بعد إكمال مهام الإعداد، يمكنك فتح دليل المصدر والبدء في إضافة الرمز كما هو موضّح في الأقسام التالية. بالنسبة إلى هذا النموذج، يجب أن يستورد مشروعك وحدتَي Cloud Functions وAdmin SDK باستخدام عبارات Node require. أضِف أسطرًا مثل ما يلي إلى ملف index.js:

// The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
const functions = require('firebase-functions/v1');

// The Firebase Admin SDK to access Firestore.
const admin = require("firebase-admin");
admin.initializeApp();

تعمل هذه الأسطر على تحميل الوحدتَين firebase-functions وfirebase-admin، وتهيئة مثيل تطبيق admin يمكن من خلاله إجراء تغييرات Cloud Firestore. في أي مكان يتوفّر فيه دعم Admin SDK، كما هو الحال مع FCM وAuthentication وFirebase Realtime Database، يوفّر طريقة فعّالة لدمج Firebase باستخدام Cloud Functions.

تثبِّت واجهة سطر الأوامر (CLI) Firebase تلقائيًا حزمة تطوير البرامج (SDK) الخاصة ببرنامج Firebase وحزمة Firebase لوحدات Cloud Functions Node عند بدء مشروعك. لإضافة مكتبات تابعة لجهات خارجية إلى مشروعك، يمكنك تعديل package.json وتشغيل npm install. لمزيد من المعلومات، يُرجى الاطّلاع على التعامل مع التبعيات.

إضافة الدالة addMessage()

بالنسبة إلى الدالة addMessage()، أضِف الأسطر التالية إلى index.js:

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addMessage = functions.https.onRequest(async (req, res) => {
  // Grab the text parameter.
  const original = req.query.text;
  // Push the new message into Firestore using the Firebase Admin SDK.
  const writeResult = await admin
    .firestore()
    .collection("messages")
    .add({ original: original });
  // Send back a message that we've successfully written the message
  res.json({ result: `Message with ID: ${writeResult.id} added.` });
});

الدالة addMessage() هي نقطة نهاية HTTP. يؤدي أي طلب إلى نقطة النهاية إلى تمرير كائنَي الطلب والاستجابة بنمط ExpressJS إلى وظيفة رد الاتصال onRequest().

تكون دوال HTTP متزامنة (على غرار الدوال القابلة للاستدعاء)، لذا عليك إرسال رد في أسرع وقت ممكن وتأجيل العمل باستخدام Cloud Firestore. تمرِّر دالة addMessage() HTTP قيمة نصية إلى نقطة نهاية HTTP وتُدرجها في قاعدة البيانات ضمن المسار /messages/:documentId/original.

إضافة الدالة makeUppercase()

بالنسبة إلى الدالة makeUppercase()، أضِف الأسطر التالية إلى index.js:

// Listens for new messages added to /messages/:documentId/original and creates an
// uppercase version of the message to /messages/:documentId/uppercase
exports.makeUppercase = functions.firestore
  .document("/messages/{documentId}")
  .onCreate((snap, context) => {
    // Grab the current value of what was written to Firestore.
    const original = snap.data().original;

    // Access the parameter `{documentId}` with `context.params`
    functions.logger.log("Uppercasing", context.params.documentId, original);

    const uppercase = original.toUpperCase();

    // You must return a Promise when performing asynchronous tasks inside a Functions such as
    // writing to Firestore.
    // Setting an 'uppercase' field in Firestore document returns a Promise.
    return snap.ref.set({ uppercase }, { merge: true });
  });

يتم تنفيذ الدالة makeUppercase() عند كتابة Cloud Firestore. تحدّد الدالة ref.set المستند الذي سيتم الاستماع إليه. لأسباب متعلّقة بالأداء، يجب أن تكون محدّدًا قدر الإمكان.

تحيط الأقواس المعقوفة، مثل {documentId}، بـ "المَعلمات"، وهي أحرف بدل تعرض البيانات المطابقة في دالة رد الاتصال.

يؤدي Cloud Firestore إلى تفعيل onCreate() كلما تمت إضافة رسائل جديدة.

أي أن تؤدي إلى النتيجة نفسها إذا تم تنفيذها عدة مرات لحدث واحد.

تكون الدوال المستندة إلى الأحداث، مثل أحداث Cloud Firestore، غير متزامنة. يجب أن تعرض دالة رد الاتصال إما null أو Object أو Promise. إذا لم تعرض أي بيانات، ستنتهي مهلة الدالة، ما يشير إلى حدوث خطأ، وستتم إعادة المحاولة. اطّلِع على المزامنة وغير المتزامنة والوعود.

محاكاة تنفيذ الدوال

تتيح لك Firebase Local Emulator Suite إنشاء التطبيقات واختبارها على جهازك المحلي بدلاً من نشرها في مشروع على Firebase. ننصح بشدة بإجراء اختبارات محلية أثناء عملية التطوير، وذلك جزئيًا لأنّها تقلّل من مخاطر أخطاء الترميز التي قد تؤدي إلى تكبّد تكاليف في بيئة الإنتاج (على سبيل المثال، حلقة لا نهائية).

لمحاكاة الدوال، اتّبِع الخطوات التالية:

  1. نفِّذ firebase emulators:start وتحقّق من الناتج بحثًا عن عنوان URL الخاص بـ Emulator Suite UI. يكون العنوان التلقائي هو localhost:4000، ولكن قد تتم استضافته على منفذ مختلف على جهازك. أدخِل عنوان URL هذا في المتصفّح لفتح Emulator Suite UI.

  2. تحقَّق من ناتج الأمر firebase emulators:start للحصول على عنوان URL لدالة HTTP addMessage(). سيبدو مشابهًا لما يلي: http://localhost:5001/MY_PROJECT/us-central1/addMessage، باستثناء ما يلي:

    1. سيتم استبدال MY_PROJECT برقم تعريف مشروعك.
    2. قد يختلف المنفذ على جهازك المحلي.
  3. أضِف سلسلة طلب البحث ?text=uppercaseme إلى نهاية عنوان URL للدالة. من المفترض أن يظهر بالشكل التالي: http://localhost:5001/MY_PROJECT/us-central1/addMessage?text=uppercaseme. يمكنك اختياريًا تغيير الرسالة "uppercaseme" إلى رسالة مخصّصة.

  4. أنشئ رسالة جديدة من خلال فتح عنوان URL في علامة تبويب جديدة في المتصفّح.

  5. للاطّلاع على تأثيرات الدوال في Emulator Suite UI، اتّبِع الخطوات التالية:

    1. في علامة التبويب السجلات، يجب أن تظهر سجلات جديدة تشير إلى أنّ الدالتَين addMessage() وmakeUppercase() تم تنفيذهما:

      i functions: Beginning execution of "addMessage"

      i functions: Beginning execution of "makeUppercase"

    2. في علامة التبويب Firestore، من المفترض أن يظهر لك مستند يحتوي على رسالتك الأصلية بالإضافة إلى نسخة من رسالتك بأحرف كبيرة (إذا كانت الرسالة الأصلية هي "uppercaseme"، سيظهر لك "UPPERCASEME").

نشر الدوال في بيئة إنتاج

بعد التأكّد من أنّ الدوال تعمل على النحو المطلوب في المحاكي، يمكنك المتابعة إلى نشرها واختبارها وتشغيلها في بيئة الإنتاج. يُرجى العِلم أنّه لنشر مشروعك في بيئة وقت التشغيل Node.js 14، يجب أن يكون مشروعك ضمن خطة أسعار Blaze. يمكنك الاطّلاع على أسعار Cloud Functions.

لإكمال البرنامج التعليمي، عليك نشر الدوال ثم تنفيذ addMessage() لتشغيل makeUppercase().

  1. نفِّذ الأمر التالي لنشر الدوال:

     firebase deploy --only functions
     

    بعد تشغيل هذا الأمر، تعرض واجهة سطر الأوامر Firebase عنوان URL لأي نقاط نهاية لوظائف HTTP. في الوحدة الطرفية، من المفترض أن يظهر لك سطر على النحو التالي:

    Function URL (addMessage): https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage
    

    يحتوي عنوان URL على معرّف مشروعك بالإضافة إلى منطقة لوظيفة HTTP. على الرغم من أنّه ليس عليك القلق بشأن ذلك الآن، يجب أن تحدّد بعض دوال HTTP الخاصة بالإنتاج موقعًا جغرافيًا لتقليل وقت استجابة الشبكة.

    إذا واجهت أخطاء في الوصول، مثل "يتعذّر منح الإذن بالوصول إلى المشروع"، جرِّب التحقّق من تحديد الأسماء المستعارة للمشروع.

  2. باستخدام عنوان URL addMessage() الذي تعرضه واجهة سطر الأوامر، أضِف مَعلمة طلب بحث نصية، وافتحها في المتصفّح:

    https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage?text=uppercasemetoo
    

    يتم تنفيذ الدالة وإعادة توجيه المتصفّح إلى وحدة تحكّم Firebase في موقع قاعدة البيانات حيث يتم تخزين السلسلة النصية. يؤدي حدث الكتابة هذا إلى تفعيل makeUppercase()، الذي يكتب نسخة بأحرف كبيرة من السلسلة.

بعد نشر الدوال وتنفيذها، يمكنك عرض السجلات في وحدة تحكّم Google Cloud. إذا كنت بحاجة إلى حذف دوال في مرحلة التطوير أو الإنتاج، استخدِم واجهة سطر الأوامر Firebase.

في مرحلة الإنتاج، قد تحتاج إلى تحسين أداء الوظيفة والتحكّم في التكاليف من خلال ضبط الحدّ الأدنى والأقصى لعدد المثيلات التي سيتم تشغيلها. يمكنك الاطّلاع على التحكّم في سلوك تغيير الحجم للحصول على مزيد من المعلومات حول خيارات وقت التشغيل هذه.

مراجعة نموذج الرمز الكامل

في ما يلي functions/index.js المكتمل الذي يتضمّن الدالتَين addMessage() وmakeUppercase(). تتيح لك هذه الدوال تمرير مَعلمة إلى نقطة نهاية HTTP تكتب قيمة في Cloud Firestore، ثم تحوّلها عن طريق تحويل جميع الأحرف في السلسلة إلى أحرف كبيرة.

// The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
const functions = require('firebase-functions/v1');

// The Firebase Admin SDK to access Firestore.
const admin = require("firebase-admin");
admin.initializeApp();

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addMessage = functions.https.onRequest(async (req, res) => {
  // Grab the text parameter.
  const original = req.query.text;
  // Push the new message into Firestore using the Firebase Admin SDK.
  const writeResult = await admin
    .firestore()
    .collection("messages")
    .add({ original: original });
  // Send back a message that we've successfully written the message
  res.json({ result: `Message with ID: ${writeResult.id} added.` });
});

// Listens for new messages added to /messages/:documentId/original and creates an
// uppercase version of the message to /messages/:documentId/uppercase
exports.makeUppercase = functions.firestore
  .document("/messages/{documentId}")
  .onCreate((snap, context) => {
    // Grab the current value of what was written to Firestore.
    const original = snap.data().original;

    // Access the parameter `{documentId}` with `context.params`
    functions.logger.log("Uppercasing", context.params.documentId, original);

    const uppercase = original.toUpperCase();

    // You must return a Promise when performing asynchronous tasks inside a Functions such as
    // writing to Firestore.
    // Setting an 'uppercase' field in Firestore document returns a Promise.
    return snap.ref.set({ uppercase }, { merge: true });
  });

الخطوات اللاحقة

في هذه المستندات، يمكنك التعرّف على مزيد من المعلومات حول كيفية إدارة الدوال في Cloud Functions، بالإضافة إلى كيفية التعامل مع جميع أنواع الأحداث المتوافقة مع Cloud Functions.

للمزيد من المعلومات عن Cloud Functions، يمكنك أيضًا اتّباع الخطوات التالية: