مدیریت توابع (نسل اول)

شما می‌توانید توابع را با استفاده از دستورات Firebase CLI یا با تنظیم گزینه‌های زمان اجرا در کد منبع توابع خود، مستقر، حذف و تغییر دهید.

توابع را مستقر کنید

برای استقرار توابع، این دستور Firebase CLI را اجرا کنید:

firebase deploy --only functions

به طور پیش‌فرض، رابط خط فرمان فایربیس ( Firebase CLI) تمام توابع درون سورس شما را همزمان مستقر می‌کند. اگر پروژه شما شامل بیش از 5 تابع است، توصیه می‌کنیم از پرچم --only با نام توابع خاص استفاده کنید تا فقط توابعی که ویرایش کرده‌اید مستقر شوند. استقرار توابع خاص به این روش، فرآیند استقرار را سرعت می‌بخشد و به شما کمک می‌کند از مواجهه با سهمیه‌های استقرار جلوگیری کنید. به عنوان مثال:

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

هنگام استقرار تعداد زیادی از توابع، ممکن است از سهمیه استاندارد تجاوز کنید و پیام‌های خطای HTTP 429 یا 500 دریافت کنید. برای حل این مشکل، توابع را در گروه‌های 10 تایی یا کمتر مستقر کنید.

برای لیست کامل دستورات موجود، به مرجع Firebase CLI مراجعه کنید.

به طور پیش‌فرض، رابط خط فرمان فایربیس ( Firebase CLI) در پوشه functions/ به دنبال کد منبع می‌گردد. در صورت تمایل، می‌توانید توابع را در پایگاه‌های کد یا چندین مجموعه فایل سازماندهی کنید .

حذف توابع

شما می‌توانید توابع قبلاً مستقر شده را به این روش‌ها حذف کنید:

  • به صراحت در Firebase CLI با functions:delete
  • به صراحت در کنسول Google Cloud .
  • به طور ضمنی با حذف تابع از منبع قبل از استقرار.

تمام عملیات حذف، قبل از حذف تابع از محیط عملیاتی، از شما می‌خواهند که آن را تأیید کنید.

حذف صریح تابع در Firebase CLI از آرگومان‌های چندگانه و همچنین گروه‌های تابع پشتیبانی می‌کند و به شما امکان می‌دهد تابعی را که در یک منطقه خاص اجرا می‌شود، مشخص کنید. همچنین، می‌توانید اعلان تأیید را نادیده بگیرید.

# 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 منبع شما را تجزیه می‌کند و هر تابعی را که از فایل حذف شده است، از محیط عملیاتی حذف می‌کند.

تغییر نام، ناحیه یا تریگر یک تابع

اگر در حال تغییر نام یا تغییر ناحیه‌ها یا تریگر توابعی هستید که ترافیک عملیاتی را مدیریت می‌کنند، مراحل این بخش را دنبال کنید تا از دست دادن رویدادها در حین اصلاح جلوگیری شود. قبل از دنبال کردن این مراحل، ابتدا مطمئن شوید که تابع شما idempotent است، زیرا هم نسخه جدید و هم نسخه قدیمی تابع شما در طول تغییر به طور همزمان اجرا خواهند شد.

تغییر نام یک تابع

برای تغییر نام یک تابع، یک نسخه جدید با نام جدید از تابع در کد منبع خود ایجاد کنید و سپس دو دستور استقرار جداگانه را اجرا کنید. دستور اول تابع با نام جدید را مستقر می‌کند و دستور دوم نسخه مستقر شده قبلی را حذف می‌کند. برای مثال، اگر یک تابع 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 CLI)، تابع قدیمی را به طور صریح از محیط عملیاتی حذف کنید.

برای مثال، اگر یک تابع 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

کیت توسعه نرم‌افزار Firebase برای Cloud Functions ، امکان انتخاب از محیط‌های اجرایی Node.js را فراهم می‌کند. می‌توانید انتخاب کنید که تمام توابع یک پروژه منحصراً در محیط اجرایی مربوط به یکی از این نسخه‌های پشتیبانی‌شده Node.js اجرا شوند:

  • نود جی اس ۲۲
  • نود جی اس ۲۰
  • Node.js 18 (منسوخ شده)

برای اطلاعات مهم در مورد پشتیبانی مداوم برای این نسخه‌های Node.js، به برنامه پشتیبانی مراجعه کنید.

برای تنظیم نسخه Node.js:

می‌توانید نسخه را در فیلد engines در فایل package.json که در دایرکتوری functions/ شما در هنگام مقداردهی اولیه ایجاد شده است، تنظیم کنید. برای مثال، برای استفاده فقط از نسخه 20، این خط را در package.json ویرایش کنید:

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

اگر از مدیر بسته Yarn استفاده می‌کنید یا الزامات خاص دیگری برای فیلد engines دارید، می‌توانید زمان اجرای Firebase SDK for Cloud Functions را در firebase.json تنظیم کنید:

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

رابط خط فرمان (CLI) از مقداری که در firebase.json تنظیم شده است، به جای هر مقدار یا محدوده‌ای که به طور جداگانه در package.json تنظیم می‌کنید، استفاده می‌کند.

زمان اجرای Node.js خود را ارتقا دهید

برای ارتقاء زمان اجرای Node.js خود:

  1. مطمئن شوید که پروژه شما در طرح قیمت‌گذاری Blaze قرار دارد.
  2. مطمئن شوید که از Firebase CLI نسخه ۱۱.۱۸.۰ یا بالاتر استفاده می‌کنید.
  3. مقدار engines را در فایل package.json که در دایرکتوری functions/ در طول مقداردهی اولیه ایجاد شده است، تغییر دهید. برای مثال، اگر از نسخه ۱۶ به نسخه ۱۸ ارتقا می‌دهید، ورودی باید به این شکل باشد: "engines": {"node": "18"}
  4. در صورت تمایل، می‌توانید تغییرات خود را با استفاده از Firebase Local Emulator Suite آزمایش کنید.
  5. تمام توابع را مجدداً مستقر کنید.

یک سیستم ماژول Node.js انتخاب کنید

سیستم ماژول پیش‌فرض در Node.js، CommonJS (CJS) است، اما نسخه‌های فعلی Node.js از ماژول‌های ECMAScript (ESM) نیز پشتیبانی می‌کنند. Cloud Functions از هر دو پشتیبانی می‌کند.

به طور پیش‌فرض، توابع شما از CommonJS استفاده می‌کنند. این یعنی importها و exportها به این شکل هستند:

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",
   ...
  }

پس از تنظیم این مورد، از سینتکس import و export ESM استفاده کنید:

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 را تعریف می‌کند. برای مثال، این تابع حداقل ۵ نمونه را برای گرم نگه داشتن تعیین می‌کند:

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 شما مقیاس‌بندی کند، برای هر نمونه بالاتر از آن آستانه، شروع سرد را تجربه خواهید کرد.
  • شروع سرد (Cold Starts) شدیدترین تأثیر را روی برنامه‌هایی با ترافیک نامنظم دارد. اگر برنامه شما ترافیک نامنظمی دارد و مقدار 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 را تعریف می‌کند. برای مثال، این تابع محدودیت ۱۰۰ نمونه را تعیین می‌کند تا یک پایگاه داده فرضی قدیمی را تحت الشعاع قرار ندهد:

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!");
    });

تنظیم زمان انقضا و تخصیص حافظه

در برخی موارد، توابع شما ممکن است الزامات خاصی برای مقدار timeout طولانی یا تخصیص زیاد حافظه داشته باشند. می‌توانید این مقادیر را یا در کنسول Google Cloud یا در کد منبع تابع (فقط Firebase) تنظیم کنید.

برای تنظیم تخصیص حافظه و زمان انقضا در کد منبع توابع، از پارامتر runWith که در Firebase SDK for Cloud Functions 2.0.0 معرفی شده است، استفاده کنید. این گزینه زمان اجرا، یک شیء JSON مطابق با رابط RuntimeOptions را می‌پذیرد که مقادیر timeoutSeconds و memory را تعریف می‌کند. به عنوان مثال، این تابع ذخیره‌سازی از ۱ گیگابایت حافظه استفاده می‌کند و پس از ۳۰۰ ثانیه زمان انقضا دارد:

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 یا ۹ دقیقه است. مقدار حافظه‌ای که به یک تابع اعطا می‌شود، مطابق با CPU اختصاص داده شده برای آن تابع است، همانطور که در این لیست از مقادیر معتبر برای memory به تفصیل آمده است:

  • 128MB - ۲۰۰ مگاهرتز
  • 256MB - ۴۰۰ مگاهرتز
  • 512MB - ۸۰۰ مگاهرتز
  • 1GB - ۱.۴ گیگاهرتز
  • 2GB - ۲.۴ گیگاهرتز
  • 4GB - ۴.۸ گیگاهرتز
  • 8GB - ۴.۸ گیگاهرتز

برای تنظیم تخصیص حافظه و زمان انقضا در کنسول Google Cloud :

  1. در کنسول Google Cloud ، از منوی سمت چپ، Cloud Functions را انتخاب کنید.
  2. با کلیک روی نام یک تابع در لیست توابع، آن را انتخاب کنید.
  3. روی آیکون ویرایش در منوی بالا کلیک کنید.
  4. از منوی کشویی با عنوان « حافظه اختصاص داده شده» ، یک تخصیص حافظه را انتخاب کنید.
  5. برای نمایش گزینه‌های پیشرفته، روی «بیشتر» کلیک کنید و در کادر متن «زمان انتظار» تعداد ثانیه‌ها را وارد کنید.
  6. برای به‌روزرسانی تابع، روی ذخیره کلیک کنید.