إدارة الوظائف


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

نشر الدوال

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

firebase deploy --only functions

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

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

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

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

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

تنظيف عناصر النشر

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

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

للمساعدة في إدارة تكاليف التخزين، يتيح لك الإصدار 14.0.0 من Firebase وواجهة سطر الأوامر والإصدارات الأحدث إعداد Artifact Registry لسياسة تنظيف للمستودعات التي تخزّن عناصر النشر بعد كل عملية نشر دالة.

يمكنك إعداد سياسة تنظيف أو تعديلها يدويًا باستخدام الأمر functions:artifacts:setpolicy:

firebase functions:artifacts:setpolicy

يضبط هذا الأمر تلقائيًا Artifact Registry لحذف صور الحاويات التي مرّ عليها أكثر من يوم واحد. ويوفّر ذلك توازنًا معقولاً بين تقليل تكاليف التخزين والسماح بإجراء فحص محتمل للإصدارات الحديثة.

يمكنك تخصيص فترة الاحتفاظ بالبيانات باستخدام الخيار --days:

firebase functions:artifacts:setpolicy --days 7  # Delete images older than 7 days

إذا كنت تنشر الدوال في مناطق متعدّدة، يمكنك إعداد سياسة تنظيف لموقع جغرافي محدّد باستخدام الخيار --location:

$ firebase functions:artifacts:setpolicy --location europe-west1

إيقاف ميزة تنظيف العناصر

إذا كنت تفضّل إدارة عملية تنظيف الصور يدويًا، أو إذا كنت لا تريد حذف أي صور، يمكنك إيقاف سياسات التنظيف بالكامل باتّباع الخطوات التالية:

$ firebase functions:artifacts:setpolicy --none

يزيل هذا الأمر أي سياسة تنظيف حالية تم إعدادها باستخدام واجهة سطر الأوامر Firebase، ويمنع Firebase من إعداد سياسة تنظيف بعد عمليات نشر الدوال.

حذف الدوال

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

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

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

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

# Delete all functions that match the specified name in all regions.
firebase functions:delete myFunction
# Delete a specified function running in a specific region.
firebase functions:delete myFunction --region us-east-1
# Delete more than one function
firebase functions:delete myFunction myOtherFunction
# Delete a specified functions group.
firebase functions:delete groupA
# Bypass the confirmation prompt.
firebase functions:delete myFunction --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 Console أو gcloud CLI وكنت لا تريد أن يتم تجاهل هذه القيم في كل عملية نشر، اضبط الخيار preserveExternalChanges على true. عند ضبط هذا الخيار على true، يدمج Firebase خيارات وقت التشغيل المحدّدة في الرمز مع إعدادات الإصدار الحالي من الدالة الذي تم نشره، وذلك حسب الأولوية التالية:

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

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

ضبط إصدار Node.js

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

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

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

لضبط إصدار Node.js، اتّبِع الخطوات التالية:

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

  "engines": {"node": "20"}

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

  {
    "functions": {
      "runtime": "nodejs20"
    }
  }

يستخدم واجهة سطر الأوامر القيمة المحدّدة في 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. أعِد نشر جميع الدوال.

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

بشكلٍ تلقائي، يضبط 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.

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

في بعض الحالات، قد تتطلّب الدوال متطلبات خاصة، مثل قيمة مهلة طويلة أو تخصيص كبير للذاكرة. يمكنك ضبط هذه القيم إما في 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 Google Cloud، اختَر Cloud Functions من القائمة اليمنى.
  2. اختَر دالة من خلال النقر على اسمها في قائمة الدوال.
  3. انقر على رمز تعديل في القائمة العلوية.
  4. اختَر تخصيص ذاكرة من القائمة المنسدلة التي تحمل التصنيف الذاكرة المخصّصة.
  5. انقر على المزيد لعرض الخيارات المتقدّمة، وأدخِل عدد الثواني في مربّع النص المهلة.
  6. انقر على حفظ لتعديل الدالة.