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


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

  • دالة "إضافة رسالة" تعرض عنوان URL يقبل قيمة نصية ويكتبها في Cloud Firestore.
  • دالة "make uppercase" التي يتم تفعيلها عند كتابة 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 التالية:

    اختَر إما حساب Google Analytics حاليًا أو أنشئ حسابًا جديدًا.

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

  5. انقر على إنشاء مشروع (أو إضافة 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 CLI باستخدام الطريقة المفضّلة لديك. لتثبيت واجهة سطر الأوامر من خلال npm، استخدِم:

npm install -g firebase-tools

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

بدء مشروعك

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

لبدء مشروعك:

  1. شغِّل firebase login لتسجيل الدخول من خلال المتصفّح ومصادقة Firebase CLI.
  2. انتقِل إلى دليل مشروعك على Firebase.
  3. شغِّل firebase init firestore. في هذا الدليل التعليمي، يمكنك قبول القيمة الافتراضية عند طلب قواعد Firestore وملفات الفهرسة. إذا لم يسبق لك استخدام Cloud Firestore في هذا المشروع، عليك أيضًا اختيار وضع بدء وموقع جغرافي لخدمة Firestore كما هو موضّح في مقالة البدء باستخدام Cloud Firestore.
  4. شغِّل firebase init functions. تطلب منك واجهة برمجة التطبيقات اختيار قاعدة رمز برمجي حالية أو بدء قاعدة جديدة وتسميتها. عند البدء للتو، يكفي استخدام قاعدة بيانات واحدة في الموقع التلقائي. ولاحقًا، مع توسيع نطاق التنفيذ، قد تحتاج إلى تنظيم الدوالّ في قواعد البيانات.
  5. يوفّر لك CLI خيارَين لدعم اللغة:

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

  6. يوفّر لك CLI خيار تثبيت التبعيات باستخدام 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. في أي مكان تتوفّر فيه إمكانية استخدام حزمة تطوير البرامج (SDK) الخاصة بالمسؤولين، كما هو الحال في FCM وAuthentication وFirebase Realtime Database، توفّر هذه الحزمة طريقة فعّالة لدمج Firebase باستخدام Cloud Functions.

تثبِّت أداة Firebase CLI تلقائيًا حِزم تطوير البرامج (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. يؤدي أي طلب إلى نقطة النهاية إلى إنشاء كائنَي Request وResponse بأسلوب 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 دالة callback onCreate() عند إضافة رسائل جديدة.

الدوال المستندة إلى الأحداث، مثل أحداث Cloud Firestore، هي غير متزامنة. يجب أن تعرِض وظيفة ردّ الاتصال إما null أو عنصرًا أو وعدًا. إذا لم يتم عرض أيّ شيء، تنتهي مهلة الدالة، ما يشير إلى حدوث خطأ، ويتم إعادة المحاولة. اطّلِع على Sync وAsync وPromises.

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

يتيح لك IDE 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").

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

بعد أن تعمل وظائفك على النحو المطلوب في المحاكي، يمكنك المتابعة ل deploying واختبارها وتشغيلها في بيئة الإنتاج. يُرجى العِلم أنّه للنشر في بيئة التشغيل المُقترَحة 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 في مرحلة الإنتاج موقعًا جغرافيًا لمحاولة minimizing network latency (تقليل وقت استجابة الشبكة).

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

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

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

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

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

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

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

في ما يلي functions/index.js المكتمل الذي يحتوي على الدوالّ addMessage() وmakeUppercase(). تسمح لك هذه الدوال بتمرير paramter إلى نقطة نهاية 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، يمكنك أيضًا إجراء ما يلي: