مدیریت کردن کارکردها (نسل اول)

می‌توانید بااستفاده از دستورات Firebase CLI یا با تنظیم گزینه‌های زمان اجرا در کد منبع توابع، توابع را پیاده‌سازی، حذف، و اصلاح کنید.

استقرار توابع

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

firebase deploy --only functions

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

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

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

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

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

حذف کردن توابع

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

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

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

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

  • همه توابعی را که با نام مشخص‌شده در همه مناطق مطابقت دارند حذف می‌کند:

    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 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 22
  • Node.js 20
  • Node.js 18 (منسوخ)

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

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

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

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

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

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

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

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

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

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 مقیاس‌بندی شود، درخواست‌های جدید به‌مدت ۳۰ ثانیه در صف قرار می‌گیرند و سپس اگر تا آن زمان نمونه‌ای دردسترس نباشد، با کد پاسخ 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 معرفی‌شده در Firebase کیت توسعه نرم‌افزار برای Cloud Functions نسخه ۲.۰.۰ استفاده کنید. این گزینه زمان اجرا شیء 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. برای به‌روزرسانی تابع، روی ذخیره کلیک کنید.