إدارة الدوال


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

دوال النشر

لتفعيل الوظائف، يمكنك تشغيل الأمر CLI في Firebase التالي:

firebase deploy --only functions

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

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

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

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

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

حذف الدوال

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

  • بشكل صريح في واجهة سطر الأوامر بمنصة 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');

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

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

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');

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

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

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.

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

أثناء تطوير وظائف السحابة الإلكترونية لنشر Firebase بمرور الوقت، قد تحتاج إلى تغيير نوع مشغِّل الوظيفة لأسباب مختلفة. مثلاً، قد ترغب في التغيير من أحد أنواع "قاعدة بيانات Firebase في الوقت الفعلي" أو حدث Cloud Firestore إلى نوع آخر.

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

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

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

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

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

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

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 في 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 أو استخدِم gcloud CLI لعرض الإعدادات الكاملة للدالة.

ضبط إصدار Node.js

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

  • Node.js 20 (معاينة)
  • Node.js 18
  • Node.js 16
  • Node.js 14

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

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

  "engines": {"node": "18"}

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

  {
    "functions": {
      "runtime": "nodejs18" // or nodejs14, nodejs16 or 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.
  5. إعادة نشر جميع الدوال.

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

تقلِّل ميزة Cloud Functions في 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:

  • إذا عملت وظائف السحابة الإلكترونية في 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 Console:

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