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

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

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

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

firebase deploy --only functions

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

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

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

برای مشاهده فهرست کامل فرمان‌های دردسترس، به مرجع میانای خط فرمان Firebase مراجعه کنید.

به‌طور پیش‌فرض، 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 SDK برای 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"
    }
  }

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 Modules (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» یا در کد منبع تابع (فقط 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. روی ذخیره کلیک کنید تا تابع به‌روز شود.