إدارة الدوال (الجيل الأول)

يمكنك نشر الدوال وحذفها وتعديلها باستخدام أوامر واجهة سطر الأوامر (CLI) في Firebase أو من خلال ضبط خيارات وقت التشغيل في الرمز المصدر للدوال.

نشر الدوال

لنشر الدوال، نفِّذ أمر واجهة سطر الأوامر (CLI) التالي في Firebase:

firebase deploy --only functions

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

firebase deploy --only functions:addMessage,functions:makeUppercase

عند نشر عدد كبير من الدوال، قد تتجاوز الحصة العادية وتتلقّى رسائل خطأ HTTP 429 أو 500. لحلّ هذه المشكلة، يمكنك نشر الدوال في مجموعات من 10 دوال أو أقل.

يمكنك الاطّلاع على مرجع واجهة سطر أوامر Firebase للحصول على القائمة الكاملة للأوامر المتاحة.

يبحث واجهة سطر الأوامر في Firebase تلقائيًا في المجلد functions/ عن الرمز المصدر. يمكنك تنظيم الدوال في قواعد الرموز البرمجية أو مجموعات متعددة من الملفات إذا أردت.

حذف الدوال

يمكنك حذف الدوال التي تم نشرها سابقًا بالطرق التالية:

  • بشكل صريح في واجهة سطر الأوامر (CLI) في Firebase باستخدام functions:delete
  • بشكل صريح في وحدة تحكّم Google Cloud.
  • ضمنيًا عن طريق إزالة الدالة من المصدر قبل النشر

تطلب منك جميع عمليات الحذف التأكيد قبل إزالة الدالة من مرحلة الإنتاج.

يتيح حذف الدوال الصريحة في واجهة سطر الأوامر (CLI) في Firebase استخدام وسيطات متعددة بالإضافة إلى مجموعات الدوال، ويسمح لك بتحديد دالة تعمل في منطقة معيّنة. يمكنك أيضًا إلغاء طلب التأكيد.

  • يحذف هذا الأمر جميع الدوال التي تتطابق مع الاسم المحدّد في جميع المناطق:

    firebase functions:delete FUNCTION-1_NAME

  • يحذف دالة محدّدة تعمل في منطقة غير تلقائية:

    firebase functions:delete FUNCTION-1_NAME --region REGION_NAME

  • تحذف أكثر من دالة واحدة:

    firebase functions:delete FUNCTION-1_NAME FUNCTION-2_NAME

  • لحذف مجموعة دوال محدّدة:

    firebase functions:delete GROUP_NAME

  • يتخطّى طلب التأكيد:

    firebase functions:delete FUNCTION-1_NAME --force

من خلال ميزة الحذف الضمني للدوال، يحلّل firebase deploy المصدر ويزيل من الإنتاج أي دوال تمت إزالتها من الملف.

تعديل اسم دالة أو منطقتها أو عامل تشغيلها

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

إعادة تسمية دالة

لإعادة تسمية دالة، أنشئ نسخة جديدة من الدالة في المصدر باسم جديد، ثم نفِّذ أمرَي نشر منفصلَين. ينشر الأمر الأول الدالة المُسمّاة حديثًا، ويزيل الأمر الثاني الإصدار الذي تم نشره سابقًا. على سبيل المثال، إذا كانت لديك دالة Node.js باسم webhook وتريد تغييرها إلى webhookNew، يمكنك مراجعة الرمز على النحو التالي:

// before
const functions = require('firebase-functions/v1');

exports.webhook = functions.https.onRequest((req, res) => {
    res.send("Hello");
});

// after
const functions = require('firebase-functions/v1');

exports.webhookNew = functions.https.onRequest((req, res) => {
    res.send("Hello");
});

بعد ذلك، نفِّذ الأوامر التالية لنشر الدالة الجديدة:

# Deploy new function called webhookNew
firebase deploy --only functions:webhookNew

# Wait until deployment is done; now both webhookNew and webhook are running

# Delete webhook
firebase functions:delete webhook

تغيير منطقة أو مناطق دالة

إذا كنت بصدد تغيير المناطق المحدّدة لدالة تعالج زيارات الإنتاج، يمكنك منع فقدان الأحداث من خلال تنفيذ هذه الخطوات بالترتيب:

  1. أعِد تسمية الدالة وغيِّر منطقتها أو مناطقها حسب رغبتك.
  2. انشر الدالة التي تمت إعادة تسميتها، ما يؤدي إلى تشغيل الرمز نفسه مؤقتًا في مجموعتَي المناطق.
  3. احذف الدالة السابقة.

على سبيل المثال، إذا كانت لديك دالة باسم webhook منشورة حاليًا في us-central1، وأردت نقلها إلى asia-northeast1، عليك أولاً تعديل الرمز المصدر لإعادة تسمية الدالة ومراجعة المنطقة.

// before
const functions = require('firebase-functions/v1');

exports.webhook = functions
    .https.onRequest((req, res) => {
            res.send("Hello");
    });

// after
const functions = require('firebase-functions/v1');

exports.webhookAsia = functions
    .region('asia-northeast1')
    .https.onRequest((req, res) => {
            res.send("Hello");
    });

بعد ذلك، انشرها من خلال تشغيل:

firebase deploy --only functions:webhookAsia

هناك الآن دالتان متطابقتان قيد التشغيل: webhook قيد التشغيل في us-central1، وwebhookAsia قيد التشغيل في asia-northeast1.

بعد ذلك، احذف webhook:

firebase functions:delete webhook

تتوفّر الآن دالة واحدة فقط، وهي webhookAsia، ويتم تشغيلها في asia-northeast1.

تغيير نوع مشغّل دالة

أثناء تطوير عملية نشر Cloud Functions for Firebase بمرور الوقت، قد تحتاج إلى تغيير نوع مشغّل الدالة لأسباب مختلفة. على سبيل المثال، قد تريد تغيير نوع حدث Firebase Realtime Database أو Cloud Firestore إلى نوع آخر.

لا يمكن تغيير نوع حدث الدالة من خلال تغيير الرمز المصدر فقط وتشغيل firebase deploy. لتجنُّب الأخطاء، يمكنك تغيير نوع مشغّل الدالة باتّباع الإجراء التالي:

  1. عدِّل الرمز المصدر لتضمين دالة جديدة مع نوع المشغّل المطلوب.
  2. انشر الدالة، ما يؤدي إلى تشغيل الدالتَين القديمة والجديدة مؤقتًا.
  3. احذف الدالة القديمة صراحةً من الإنتاج باستخدام واجهة سطر الأوامر Firebase.

على سبيل المثال، إذا كانت لديك دالة Node.js باسم objectChanged تتضمّن نوع الحدث القديم onChange، وأردت تغييرها إلى onFinalize، عليك أولاً إعادة تسمية الدالة وتعديلها لتتضمّن نوع الحدث onFinalize.

// before
const functions = require('firebase-functions/v1');

exports.objectChanged = functions.storage.object().onChange((object) => {
    return console.log('File name is: ', object.name);
});

// after
const functions = require('firebase-functions/v1');

exports.objectFinalized = functions.storage.object().onFinalize((object) => {
    return console.log('File name is: ', object.name);
});

بعد ذلك، نفِّذ الأوامر التالية لإنشاء الدالة الجديدة أولاً، قبل حذف الدالة القديمة:

# Create new function objectFinalized
firebase deploy --only functions:objectFinalized

# Wait until deployment is done; now both objectChanged and objectFinalized are running

# Delete objectChanged
firebase functions:delete objectChanged

ضبط خيارات بيئة التشغيل

يتيح لك Cloud Functions for Firebase تحديد خيارات وقت التشغيل، مثل إصدار وقت تشغيل Node.js والمهلة لكل دالة وتخصيص الذاكرة والحد الأدنى/الأقصى لمثيلات الدوال.

كأفضل ممارسة، يجب ضبط هذه الخيارات (باستثناء إصدار Node.js) على عنصر ضبط داخل رمز الدالة. هذا الكائن RuntimeOptions هو المصدر الموثوق لخيارات وقت تشغيل الدالة، وسيتم تجاوز الخيارات التي تم ضبطها باستخدام أي طريقة أخرى (مثل وحدة تحكّم Google Cloud أو gcloud CLI).

إذا كان سير عمل التطوير يتضمّن ضبط خيارات وقت التشغيل يدويًا باستخدام وحدة تحكّم Google Cloud أو gcloud CLI ولا تريد إلغاء هذه القيم في كل عملية نشر، اضبط الخيار preserveExternalChanges على true. عند ضبط هذا الخيار على true، تدمج Firebase خيارات وقت التشغيل المحدّدة في الرمز البرمجي مع إعدادات الإصدار المنشور حاليًا من الدالة حسب الأولوية التالية:

  1. تم ضبط الخيار في رمز الدوال: تجاهُل التغييرات الخارجية.
  2. تم ضبط الخيار على RESET_VALUE في رمز الدوال: تجاهُل التغييرات الخارجية واستخدام القيمة التلقائية.
  3. لم يتم ضبط الخيار في رمز الدوال، ولكن تم ضبطه في الدالة المنشورة حاليًا: استخدِم الخيار المحدّد في الدالة المنشورة.

لا ننصح باستخدام الخيار preserveExternalChanges: true في معظم السيناريوهات لأنّ الرمز البرمجي لن يكون المصدر الموثوق الوحيد لخيارات وقت التشغيل في الدوال. إذا كنت تستخدمه، يمكنك مراجعة وحدة تحكّم Google Cloud أو استخدام gcloud CLI لعرض الإعدادات الكاملة للدالة.

ضبط إصدار Node.js

تتيح حزمة تطوير البرامج (SDK) لـ Firebase في Cloud Functions اختيار بيئة تشغيل Node.js. يمكنك اختيار تشغيل جميع الدوال في مشروع حصريًا في بيئة التشغيل المتوافقة مع أحد إصدارات Node.js المتوافقة التالية:

  • Node.js 22
  • Node.js 20
  • ‫Node.js 18 (متوقّفة نهائيًا)

يُرجى الاطّلاع على جدول الدعم للحصول على معلومات مهمة بشأن الدعم المستمر لإصدارات Node.js هذه.

لضبط إصدار Node.js:

يمكنك ضبط الإصدار في حقل engines في ملف package.json الذي تم إنشاؤه في دليل functions/ أثناء الإعداد. على سبيل المثال، لاستخدام الإصدار 20 فقط، عدِّل هذا السطر في package.json:

  "engines": {"node": "22"}

إذا كنت تستخدم أداة إدارة الحِزم Yarn أو لديك متطلبات أخرى محدّدة لحقل engines، يمكنك ضبط بيئة التشغيل لحزمة تطوير البرامج (SDK) لـ Firebase في Cloud Functions في firebase.json بدلاً من ذلك:

  {
    "functions": {
      "runtime": "nodejs22"
    }
  }

تستخدم واجهة سطر الأوامر القيمة المحدّدة في firebase.json بدلاً من أي قيمة أو نطاق تحدّده بشكل منفصل في package.json.

ترقية بيئة التشغيل Node.js

لترقية بيئة التشغيل Node.js، اتّبِع الخطوات التالية:

  1. تأكَّد من أنّ مشروعك يستخدم خطة Blaze المَرِنة.
  2. تأكَّد من استخدام الإصدار 11.18.0 أو إصدار أحدث من واجهة سطر الأوامر في Firebase.
  3. غيِّر قيمة engines في ملف package.json الذي تم إنشاؤه في دليل functions/ أثناء الإعداد. على سبيل المثال، إذا كنت ترقّي من الإصدار 16 إلى الإصدار 18، يجب أن يظهر الإدخال على النحو التالي: "engines": {"node": "18"}
  4. يمكنك اختياريًا اختبار التغييرات باستخدام Firebase Local Emulator Suite.
  5. أعِد نشر جميع الدوال.

اختيار نظام وحدة Node.js

نظام الوحدات التلقائي في Node.js هو CommonJS (CJS)، ولكن إصدارات Node.js الحالية تتيح أيضًا استخدام وحدات ECMAScript (ESM). يتيح Cloud Functions كلا الخيارَين.

تستخدم الدوالّ تلقائيًا CommonJS. هذا يعني أن عمليات الاستيراد والتصدير تبدو على النحو التالي:

const functions = require("firebase-functions/v1");

exports.helloWorld = functions.https.onRequest(async (req, res) => res.send("Hello from Firebase!"));

لاستخدام ESM بدلاً من ذلك، اضبط الحقل "type": "module" في ملف package.json :

  {
   ...
   "type": "module",
   ...
  }

بعد ضبط هذا الإعداد، استخدِم بنية ESM import وexport:

import functions from "firebase-functions/v1";

export const helloWorld = functions.https.onRequest(async (req, res) => res.send("Hello from Firebase!"));

كلا نظامَي الوحدات متوافقان بالكامل. يمكنك اختيار أي منها يناسب مشروعك بشكل أفضل. يمكنك الاطّلاع على مزيد من المعلومات في مستندات Node.js حول الوحدات.

التحكّم في سلوك تغيير الحجم

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

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

تقليل عدد عمليات التشغيل على البارد

لضبط الحدّ الأدنى لعدد النُسخ لدالة في الرمز المصدر، استخدِم طريقة runWith. يقبل هذا الإجراء عنصر JSON يتوافق مع واجهة RuntimeOptions التي تحدّد قيمة minInstances. على سبيل المثال، تحدّد هذه الدالة الحد الأدنى لعدد النُسخ التي يجب إبقاؤها نشطة بـ 5:

exports.getAutocompleteResponse = functions
    .runWith({
      // Keep 5 instances warm for this latency-critical function
      minInstances: 5,
    })
    .https.onCall((data, context) => {
      // Autocomplete a user's search term
    });

في ما يلي بعض النقاط التي يجب مراعاتها عند ضبط قيمة لسمة minInstances:

  • إذا وسّع Cloud Functions for Firebase نطاق تطبيقك ليتجاوز إعداد minInstances، سيتم تشغيل كل مثيل يتجاوز هذا الحد على البارد.
  • تؤثر عمليات التشغيل على البارد بشكل كبير في التطبيقات التي تشهد ارتفاعًا مفاجئًا في عدد الزيارات. إذا كان تطبيقك يتلقّى عددًا كبيرًا من الزيارات في أوقات معيّنة، وضبطت قيمة minInstances عالية بما يكفي لتقليل عمليات التشغيل على البارد مع كل زيادة في عدد الزيارات، ستلاحظ انخفاضًا كبيرًا في وقت الاستجابة. بالنسبة إلى التطبيقات التي تتلقّى عددًا ثابتًا من الزيارات، من غير المرجّح أن تؤثّر عمليات التشغيل على البارد في الأداء بشكل كبير.
  • قد يكون من المنطقي ضبط الحد الأدنى لعدد النُسخ في بيئات التشغيل الفعلي، ولكن يجب تجنُّب ذلك عادةً في بيئات الاختبار. لتقليل عدد النُسخ إلى الصفر في مشروعك التجريبي مع تقليل عمليات التشغيل على البارد في مشروع الإنتاج، يمكنك ضبط minInstances استنادًا إلى متغيّر البيئة FIREBASE_CONFIG:

    // Get Firebase project id from `FIREBASE_CONFIG` environment variable
    const envProjectId = JSON.parse(process.env.FIREBASE_CONFIG).projectId;
    
    exports.renderProfilePage = functions
        .runWith({
          // Keep 5 instances warm for this latency-critical function
          // in production only. Default to 0 for test projects.
          minInstances: envProjectId === "my-production-project" ? 5 : 0,
        })
        .https.onRequest((req, res) => {
          // render some html
        });
    

الحدّ من الحدّ الأقصى لعدد النُسخ لدالة معيّنة

لضبط الحد الأقصى لعدد النُسخ في الرمز المصدر للدالة، استخدِم الطريقة runWith. يقبل هذا الإجراء عنصر JSON يتوافق مع واجهة RuntimeOptions التي تحدّد قيم maxInstances. على سبيل المثال، تضع هذه الدالة حدًا أقصى يبلغ 100 مثيل لكي لا تضغط على قاعدة بيانات قديمة افتراضية:

exports.mirrorOrdersToLegacyDatabase = functions
    .runWith({
      // Legacy database only supports 100 simultaneous connections
      maxInstances: 100,
    })
    .firestore.document("orders/{orderId}")
    .onWrite((change, context) => {
      // Connect to legacy database
    });

إذا تم توسيع نطاق دالة HTTP إلى الحد الأقصى البالغ maxInstances، تتم إضافة الطلبات الجديدة إلى قائمة الانتظار لمدة 30 ثانية ثم يتم رفضها برمز الاستجابة 429 Too Many Requests إذا لم يتوفّر أي مثيل بحلول ذلك الوقت.

لمزيد من المعلومات حول أفضل الممارسات لاستخدام إعدادات الحد الأقصى لعدد النُسخ، يُرجى الاطّلاع على أفضل الممارسات لاستخدام maxInstances.

ضبط حساب خدمة

يحتوي حساب الخدمة التلقائي لدوال الجيل الأول، PROJECT_ID@appspot.gserviceaccount.com (المسمى حساب الخدمة التلقائي لـ App Engine)، على مجموعة واسعة من الأذونات للسماح لك بالتفاعل مع خدمات Firebase وGoogle Cloud الأخرى.

قد تحتاج إلى إلغاء حساب الخدمة التلقائي وحصر وظيفة معيّنة بالموارد المطلوبة فقط. يمكنك إجراء ذلك من خلال إنشاء حساب خدمة مخصّص وتعيينه للدالة المناسبة باستخدام طريقة .runWith(). تتطلّب هذه الطريقة عنصرًا يتضمّن خيارات الضبط، بما في ذلك السمة serviceAccount.

const functions = require("firebase-functions/v1");

exports.helloWorld = functions
    .runWith({
        // This function doesn't access other Firebase project resources, so it uses a limited service account.
        serviceAccount:
            "my-limited-access-sa@", // or prefer the full form: "my-limited-access-sa@my-project.iam.gserviceaccount.com"
    })
    .https.onRequest((request, response) => {
        response.send("Hello from Firebase!");
    });

ضبط المهلة وتخصيص الذاكرة

في بعض الحالات، قد تتطلّب دوالّك متطلبات خاصة لقيمة مهلة طويلة أو تخصيص كبير للذاكرة. يمكنك ضبط هذه القيم إما في Google Cloud Console أو في الرمز المصدر للدالة (Firebase فقط).

لضبط تخصيص الذاكرة والمهلة في الرمز المصدر للدوال، استخدِم المَعلمة runWith التي تم تقديمها في حزمة تطوير البرامج (SDK) لخدمة Firebase للإصدار 2.0.0 من Cloud Functions. يقبل خيار وقت التشغيل هذا كائن JSON يتوافق مع واجهة RuntimeOptions التي تحدّد قيم timeoutSeconds وmemory. على سبيل المثال، تستخدم دالة التخزين هذه 1 غيغابايت من الذاكرة وتنتهي مهلتها بعد 300 ثانية:

exports.convertLargeFile = functions
    .runWith({
      // Ensure the function has enough memory and time
      // to process large files
      timeoutSeconds: 300,
      memory: "1GB",
    })
    .storage.object()
    .onFinalize((object) => {
      // Do some complicated things that take a lot of memory and time
    });

الحدّ الأقصى لقيمة timeoutSeconds هو 540، أو 9 دقائق. يتوافق مقدار الذاكرة الممنوحة لدالة مع وحدة المعالجة المركزية المخصّصة للدالة، كما هو موضّح في قائمة القيم الصالحة لـ memory:

  • ‫128MB — 200 ميغاهرتز
  • ‫256MB — 400 ميغاهرتز
  • ‫512MB — 800 ميغاهرتز
  • ‫1GB — 1.4 غيغاهرتز
  • ‫2GB — 2.4 غيغاهرتز
  • ‫4GB — 4.8 غيغاهرتز
  • ‫8GB — 4.8 غيغاهرتز

لضبط تخصيص الذاكرة والمهلة في وحدة تحكّم Google Cloud:

  1. في وحدة تحكّم Google Cloud، اختَر Cloud Functions من القائمة اليمنى.
  2. اختَر دالة من خلال النقر على اسمها في قائمة الدوال.
  3. انقر على رمز تعديل في القائمة في أعلى الشاشة.
  4. اختَر مقدارًا لتخصيص الذاكرة من القائمة المنسدلة الذاكرة المخصّصة.
  5. انقر على المزيد لعرض الخيارات المتقدّمة، وأدخِل عدد الثواني في مربّع النص مهلة.
  6. انقر على حفظ لتعديل الدالة.