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


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

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

في ما يلي نموذج الرمز البرمجي الكامل الذي يحتوي على الدوالّ:

Node.js

// The Cloud Functions for Firebase SDK to create Cloud Functions and triggers.
const {logger} = require("firebase-functions");
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");

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

initializeApp();

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addmessage = 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 getFirestore()
      .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 saves an uppercased version of the message
// to /messages/:documentId/uppercase
exports.makeuppercase = onDocumentCreated("/messages/{documentId}", (event) => {
  // Grab the current value of what was written to Firestore.
  const original = event.data.data().original;

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

  const uppercase = original.toUpperCase();

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

Python

# The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
from firebase_functions import firestore_fn, https_fn

# The Firebase Admin SDK to access Cloud Firestore.
from firebase_admin import initialize_app, firestore
import google.cloud.firestore

app = initialize_app()


@https_fn.on_request()
def addmessage(req: https_fn.Request) -> https_fn.Response:
    """Take the text parameter passed to this HTTP endpoint and insert it into
    a new document in the messages collection."""
    # Grab the text parameter.
    original = req.args.get("text")
    if original is None:
        return https_fn.Response("No text parameter provided", status=400)

    firestore_client: google.cloud.firestore.Client = firestore.client()

    # Push the new message into Cloud Firestore using the Firebase Admin SDK.
    _, doc_ref = firestore_client.collection("messages").add({"original": original})

    # Send back a message that we've successfully written the message
    return https_fn.Response(f"Message with ID {doc_ref.id} added.")


@firestore_fn.on_document_created(document="messages/{pushId}")
def makeuppercase(event: firestore_fn.Event[firestore_fn.DocumentSnapshot | None]) -> None:
    """Listens for new documents to be added to /messages. If the document has
    an "original" field, creates an "uppercase" field containg the contents of
    "original" in upper case."""

    # Get the value of "original" if it exists.
    if event.data is None:
        return
    try:
        original = event.data.get("original")
    except KeyError:
        # No "original" field, so do nothing.
        return

    # Set the "uppercase" field.
    print(f"Uppercasing {event.params['pushId']}: {original}")
    upper = original.upper()
    event.data.reference.update({"uppercase": upper})

لمحة عن هذا الدليل التوجيهي

لقد اخترنا Cloud Firestore والدوالّ التي يتم تشغيلها من خلال HTTP لهذا المثال، ويعود السبب جزئيًا إلى أنّه يمكن اختبار عوامل التفعيل هذه التي تعمل في الخلفية بشكل كامل من خلال Firebase Local Emulator Suite. مجموعة الأدوات هذه يتوافق مع Realtime Database وCloud Storage مشغِّلات PubSub وAuth وHTTP القابلة للاستدعاء. يمكن اختبار الأنواع الأخرى من عوامل التفعيل التي تعمل في الخلفية، مثل عوامل التفعيل في Remote Config وTestLab، بشكل تفاعلي باستخدام مجموعات أدوات غير описанة في هذه الصفحة.

توضح الأقسام التالية من هذا البرنامج التعليمي الخطوات المطلوبة لإنشاء واختبارها ونشر العينة.

إنشاء مشروع على 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.

إعداد البيئة وواجهة سطر الأوامر في Firebase

Node.js

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

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

npm install -g firebase-tools

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

Python

ستحتاج إلى بيئة Python لكتابة الدوال، وستحتاج إلى Firebase CLI لنشر الدوال بيئة تشغيل Cloud Functions ننصح باستخدام venv لمحاولة عزل التبعيات. يمكن استخدام الإصدارَين 3.10 و3.11 من Python.

بعد تثبيت Python، ثبِّت Firebase CLI باستخدام الطريقة المفضّلة لديك.

إعداد مشروعك

عند إعداد حزمة تطوير برامج (SDK) "Firebase" لمؤسسة "Cloud Functions"، يمكنك إنشاء مشروع فارغ. تحتوي على التبعيات وبعض الحد الأدنى من نموذج التعليمات البرمجية. إذا كنت باستخدام Node.js، يمكنك اختيار إما 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
    • TypeScript
    • Python

    في هذا الدليل التعليمي، اختَر JavaScript أو Python. للتأليف باللغة TypeScript، يُرجى الاطّلاع على كتابة الدوال باستخدام TypeScript.

  6. تمنحك واجهة برمجة التطبيقات خيار تثبيت التبعيات. هذا آمن للرفض إذا كنت تريد إدارة التبعيات بطريقة أخرى.

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

Node.js

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

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

Python

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
      |
      +- main.py      # Main source file for your Cloud Functions code
      |
      +- requirements.txt  #  List of the project's modules and packages 
      |
      +- venv/ # Directory where your dependencies are installed

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

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

Node.js

// The Cloud Functions for Firebase SDK to create Cloud Functions and triggers.
const {logger} = require("firebase-functions");
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");

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

initializeApp();

Python

# The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
from firebase_functions import firestore_fn, https_fn

# The Firebase Admin SDK to access Cloud Firestore.
from firebase_admin import initialize_app, firestore
import google.cloud.firestore

app = initialize_app()

تحمِّل هذه الأسطر الوحدات المطلوبة و تُنشئ مثيل تطبيق admin يمكن من خلاله إجراء تغييرات Cloud Firestore. في أيّ مكان تتوفّر فيه إمكانية استخدام حزمة تطوير البرامج (SDK) الخاصة بالمسؤولين، كما هو الحال في FCM وAuthentication وFirebase Realtime Database، توفّر هذه الحزمة طريقة فعّالة لدمج Firebase باستخدام Cloud Functions.

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

إضافة "إضافة رسالة" الوظيفة

بالنسبة إلى خيار "إضافة رسالة" أضف هذه الأسطر إلى ملف المصدر:

Node.js

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addmessage = 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 getFirestore()
      .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.`});
});

Python

@https_fn.on_request()
def addmessage(req: https_fn.Request) -> https_fn.Response:
    """Take the text parameter passed to this HTTP endpoint and insert it into
    a new document in the messages collection."""
    # Grab the text parameter.
    original = req.args.get("text")
    if original is None:
        return https_fn.Response("No text parameter provided", status=400)

    firestore_client: google.cloud.firestore.Client = firestore.client()

    # Push the new message into Cloud Firestore using the Firebase Admin SDK.
    _, doc_ref = firestore_client.collection("messages").add({"original": original})

    # Send back a message that we've successfully written the message
    return https_fn.Response(f"Message with ID {doc_ref.id} added.")

زر "إضافة رسالة" هي نقطة نهاية HTTP. أي طلب إلى نقطة النهاية النتائج إلى تمرير كائنات الطلب والاستجابة إلى معالِج الطلب لمنصتك (onRequest() أو on_request).

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

إضافة الدالة make uppercase

بالنسبة إلى "جعل الأحرف الكبيرة" أضف هذه الأسطر إلى ملف المصدر:

Node.js

// Listens for new messages added to /messages/:documentId/original
// and saves an uppercased version of the message
// to /messages/:documentId/uppercase
exports.makeuppercase = onDocumentCreated("/messages/{documentId}", (event) => {
  // Grab the current value of what was written to Firestore.
  const original = event.data.data().original;

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

  const uppercase = original.toUpperCase();

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

Python

@firestore_fn.on_document_created(document="messages/{pushId}")
def makeuppercase(event: firestore_fn.Event[firestore_fn.DocumentSnapshot | None]) -> None:
    """Listens for new documents to be added to /messages. If the document has
    an "original" field, creates an "uppercase" field containg the contents of
    "original" in upper case."""

    # Get the value of "original" if it exists.
    if event.data is None:
        return
    try:
        original = event.data.get("original")
    except KeyError:
        # No "original" field, so do nothing.
        return

    # Set the "uppercase" field.
    print(f"Uppercasing {event.params['pushId']}: {original}")
    upper = original.upper()
    event.data.reference.update({"uppercase": upper})

يعني "إنشاء أحرف كبيرة" يتم تنفيذ الدالة عند كتابة Cloud Firestore إلى، وتحديد المستند للاستماع إليه. لأسباب تتعلّق بالأداء، يجب أن تكون دقيقًا قدر الإمكان.

تحيط الأقواس، مثل {documentId}، بـ "المَعلمات"، وهي العناصر النائبة التي تعرض بياناتها المطابقة في دالة "مكالمة إعادة الاتصال". يشغِّل Cloud Firestoreدالة callback عند إضافة رسائل جديدة.

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

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

تشير رسالة الأشكال البيانية 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. سيبدو مشابهًا لرمز 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 UI:

    1. في علامة التبويب السجلات، من المفترض أن تظهر لك سجلات جديدة تشير إلى ما يلي: تم تشغيل دوال HTTP بنجاح:

      i functions: Beginning execution of "addMessage"

      i functions: Beginning execution of "makeUppercase"

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

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

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

لإكمال البرنامج التعليمي، انشر الدوال ثم قم بتنفيذها. معهم.

  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 بواسطة واجهة سطر الأوامر، أضف معلَمة طلب بحث نصي، وفتحه في المتصفح:

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

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

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

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

الخطوات التالية

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

للاطّلاع على مزيد من المعلومات عن Cloud Functions، يمكنك أيضًا إجراء ما يلي: