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


لبدء استخدام دوال السحابة، يُرجى محاولة العمل من خلال هذا البرنامج التعليمي، الذي يبدأ بمهام الإعداد المطلوبة ويعمل من خلال إنشاء دالتَين مرتبطتَين واختبارهما ونشرهما:

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

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

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

إنشاء مشروع في Firebase

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

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

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

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

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

  4. (اختياري) يمكنك إعداد "إحصاءات Google" لمشروعك، ما يتيح لك الحصول على تجربة مثالية باستخدام أيٍّ من منتجات Firebase التالية:

    اختيار حساب حالي على "إحصاءات Google" أو إنشاء حساب جديد

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

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

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

إعداد Node.js وواجهة سطر الأوامر لمنصة Firebase

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

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

npm install -g firebase-tools

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

تهيئة مشروعك

عند إعداد حزمة تطوير البرامج (SDK) لمنصّة Firebase الخاصة بوظائف السحابة الإلكترونية، يمكنك إنشاء مشروع فارغ يحتوي على التبعيات والحد الأدنى من نموذج الرمز البرمجي، ويمكنك اختيار 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 ووحدة 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 والمصادقة وقاعدة بيانات Firebase في الوقت الفعلي، فإنّه يوفّر طريقة فعّالة لدمج Firebase باستخدام وظائف السحابة الإلكترونية.

تعمل واجهة سطر الأوامر في Firebase على تثبيت حزمة SDK لمنصة Firebase وFirebase تلقائيًا لوحدات عُقد الوظائف في السحابة الإلكترونية عند إعداد مشروعك. لإضافة مكتبات تابعة لجهات خارجية إلى مشروعك، يمكنك تعديل 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. تمرِّر دالة HTTP addMessage() قيمة نصية إلى نقطة نهاية 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 أو كائنًا أو Promise. إذا لم تعرض أي شيء، تنتهي مهلة الدالة، وتشير إلى خطأ، ثم تتم إعادة المحاولة. يُرجى الاطّلاع على المزامنة وغير المزامنة والوعد.

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

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

لمحاكاة الدوال:

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

  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. يمكنك بشكل اختياري تغيير الرسالة ذات الحالة "كبيرة الحجم" إلى رسالة مخصّصة.

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

  5. عرض تأثيرات الدوال في واجهة مستخدم Emulator Suite:

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

      i functions: Beginning execution of "addMessage"

      i functions: Beginning execution of "makeUppercase"

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

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

وبمجرد أن تعمل الدوال على النحو المطلوب في المحاكي، يمكنك متابعة نشرها واختبارها وتشغيلها في بيئة الإنتاج. ضَع في اعتبارك أنّه للنشر في بيئة وقت تشغيل 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 Console. إذا كنت بحاجة إلى حذف وظائف قيد التطوير أو الإنتاج، استخدِم واجهة سطر الأوامر في 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.

لمعرفة المزيد حول دوال السحابة، يمكنك أيضًا القيام بما يلي: