محیط خود را پیکربندی کنید


اغلب برای عملکردهای خود به پیکربندی اضافی نیاز دارید، مانند کلیدهای API شخص ثالث یا تنظیمات قابل تنظیم. Firebase SDK for Cloud Functions پیکربندی محیط داخلی را ارائه می دهد تا ذخیره و بازیابی این نوع داده ها را برای پروژه شما آسان کند.

می توانید بین این گزینه ها یکی را انتخاب کنید:

  • پیکربندی پارامتری (برای اکثر سناریوها توصیه می شود). این پیکربندی محیطی با تایپ قوی با پارامترهایی را فراهم می کند که در زمان استقرار تأیید می شوند، که از خطاها جلوگیری می کند و اشکال زدایی را ساده می کند.
  • پیکربندی مبتنی بر فایل متغیرهای محیطی . با این روش، شما به صورت دستی یک فایل dotenv برای بارگیری متغیرهای محیطی ایجاد می کنید.

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

پیکربندی پارامتری شده

Cloud Functions for Firebase یک رابط برای تعریف پارامترهای پیکربندی به صورت اعلامی در پایگاه کد شما فراهم می کند. مقدار این پارامترها هم در حین استقرار تابع، هم هنگام تنظیم گزینه های استقرار و زمان اجرا و هم در حین اجرا در دسترس است. این بدان معنی است که CLI استقرار را مسدود می کند مگر اینکه همه پارامترها دارای یک مقدار معتبر باشند.

برای تعریف پارامترها در کد خود، این مدل را دنبال کنید:

const functions = require('firebase-functions/v1');
const { defineInt, defineString } = require('firebase-functions/params');

// Define some parameters
const minInstancesConfig = defineInt('HELLO_WORLD_MININSTANCES');
const welcomeMessage = defineString('WELCOME_MESSAGE');

// To use configured parameters inside the config for a function, provide them
// directly. To use them at runtime, call .value() on them.
export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
  (req, res) => {
    res.send(`${welcomeMessage.value()}! I am a function.`);
  }
);

هنگام استقرار یک تابع با متغیرهای پیکربندی پارامتر شده، Firebase CLI ابتدا سعی می کند مقادیر آنها را از فایل های .env محلی بارگیری کند. اگر در آن فایل‌ها وجود نداشته باشند و هیچ default تنظیم نشده باشد، CLI مقادیر را در حین استقرار درخواست می‌کند، و سپس به‌طور خودکار مقادیر آن‌ها را در یک فایل .env با نام .env.<project_ID> در فهرست functions/ ذخیره می‌کند:

$ firebase deploy
i  functions: preparing codebase default for deployment
? Enter a string value for ENVIRONMENT: prod
i  functions: Writing new parameter values to disk: .env.projectId
…
$ firebase deploy
i  functions: Loaded environment variables from .env.projectId

بسته به گردش کار توسعه شما، ممکن است مفید باشد که فایل .env.<project_ID> ایجاد شده را به کنترل نسخه اضافه کنید.

استفاده از پارامترها در گستره جهانی

در طول استقرار، کد توابع شما قبل از اینکه پارامترهای شما مقادیر واقعی داشته باشند، بارگیری و بازرسی می شود. این بدان معنی است که واکشی مقادیر پارامتر در طول دامنه جهانی منجر به شکست استقرار می شود. برای مواردی که می خواهید از پارامتری برای مقداردهی اولیه استفاده کنید، از callback اولیه onInit() استفاده کنید. این فراخوانی قبل از اجرای هر توابعی در تولید اجرا می شود اما در طول زمان استقرار فراخوانی نمی شود، بنابراین مکان امنی برای دسترسی به مقدار پارامتر است.

  const { GoogleGenerativeAI } = require('@google/generative-ai');
  const { defineSecret } = require('firebase-functions/params');
  const { onInit } = require('firebase-functions/v1');

  const apiKey = defineSecret('GOOGLE_API_KEY');

  let genAI;
  onInit(() => {
    genAI = new GoogleGenerativeAI(apiKey.value());
  })

پیکربندی رفتار CLI

پارامترها را می توان با یک شی Options پیکربندی کرد که کنترل می کند CLI چگونه مقادیر را درخواست می کند. مثال زیر گزینه هایی را برای تأیید فرمت شماره تلفن، ارائه یک گزینه انتخاب ساده و پر کردن یک گزینه انتخاب به طور خودکار از پروژه Firebase تنظیم می کند:

const { defineString } = require('firebase-functions/params');

const welcomeMessage = defineString('WELCOME_MESSAGE', {default: 'Hello World',
description: 'The greeting that is returned to the caller of this function'});

const onlyPhoneNumbers = defineString('PHONE_NUMBER', {input: {text:
{validationRegex: /\d{3}-\d{3}-\d{4}/, validationErrorMessage: "Please enter
a phone number in the format XXX-YYY-ZZZZ"}}});

const selectedOption = defineString('PARITY', {input: {select: {options:
[{value: "odd"}, {value: "even"}]}}})

const storageBucket = defineString('BUCKET', {input: {resource: {type:
"storage.googleapis.com/Bucket"}}, description: "This will automatically
populate the selector field with the deploying Cloud Project’s
storage buckets"})

انواع پارامترها

پیکربندی پارامتری تایپ قوی برای مقادیر پارامترها را فراهم می کند و همچنین از اسرار Cloud Secret Manager پشتیبانی می کند. انواع پشتیبانی شده عبارتند از:

  • راز
  • رشته
  • بولی
  • عدد صحیح
  • شناور

مقادیر و عبارات پارامتر

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

برای ارسال یک پارامتر به تابع خود به عنوان گزینه زمان اجرا، آن را مستقیماً ارسال کنید:

const functions = require('firebase-functions/v1');
const { defineInt} = require('firebase-functions/params');
const minInstancesConfig = defineInt('HELLO\_WORLD\_MININSTANCES');

export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
  (req, res) => {
    //…

علاوه بر این، اگر برای اینکه بدانید چه گزینه ای را انتخاب کنید، نیاز به مقایسه با یک پارامتر دارید، به جای بررسی مقدار، باید از مقایسه کننده های داخلی استفاده کنید:

const functions = require('firebase-functions/v1');
const { defineBool } = require('firebase-functions/params');
const environment = params.defineString(ENVIRONMENT, {default: dev});

// use built-in comparators
const minInstancesConfig =environment.equals('PRODUCTION').thenElse(10, 1);
export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
  (req, res) => {
    //…

پارامترها و عبارات پارامتری که فقط در زمان اجرا مورد استفاده قرار می‌گیرند را می‌توان با تابع value در دسترس قرار داد:

const functions = require('firebase-functions/v1');
const { defineString } = require('firebase-functions/params');
const welcomeMessage = defineString('WELCOME_MESSAGE');

// To use configured parameters inside the config for a function, provide them
// directly. To use them at runtime, call .value() on them.
export const helloWorld = functions.https.onRequest(
 (req, res) => {
    res.send(`${welcomeMessage.value()}! I am a function.`);
  }
);

پارامترهای داخلی

Cloud Functions SDK سه پارامتر از پیش تعریف شده را ارائه می دهد که در زیر بسته firebase-functions/params موجود است:

  • projectID - پروژه ابری که تابع در آن اجرا می شود.
  • databaseURL - URL نمونه پایگاه داده بیدرنگ مرتبط با تابع (اگر در پروژه Firebase فعال باشد).
  • storageBucket - سطل ذخیره سازی ابری مرتبط با این تابع (در صورت فعال بودن در پروژه Firebase).

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

پارامترهای مخفی

پارامترهای نوع Secret که با استفاده از defineSecret() تعریف می شوند، پارامترهای رشته ای را نشان می دهند که دارای مقدار ذخیره شده در Cloud Secret Manager هستند. به جای بررسی یک فایل .env محلی و نوشتن یک مقدار جدید در فایل در صورت عدم وجود، پارامترهای مخفی وجود را در Cloud Secret Manager بررسی می کنند و به طور تعاملی مقدار یک راز جدید را در حین استقرار درخواست می کنند.

پارامترهای مخفی تعریف شده به این روش باید به توابع جداگانه ای که باید به آنها دسترسی داشته باشند متصل شوند:

const functions = require('firebase-functions/v1');
const { defineSecret } = require('firebase-functions/params');
const discordApiKey = defineSecret('DISCORD_API_KEY');

export const postToDiscord = functions.runWith({ secrets: [discordApiKey] }).https.onRequest(
  (req, res) => {
    const apiKey = discordApiKey.value();
    //…

از آنجایی که مقادیر Secret ها تا زمان اجرای تابع مخفی هستند، نمی توانید هنگام پیکربندی تابع خود از آنها استفاده کنید.

متغیرهای محیطی

Cloud Functions for Firebase از فرمت فایل dotenv برای بارگیری متغیرهای محیطی مشخص شده در فایل .env در زمان اجرای برنامه شما پشتیبانی می کند. پس از استقرار، متغیرهای محیطی را می توان از طریق رابط process.env خواند.

برای پیکربندی محیط خود به این روش، یک فایل .env در پروژه خود ایجاد کنید، متغیرهای مورد نظر را اضافه کنید و اجرا کنید:

  1. یک فایل .env در functions/ دایرکتوری خود ایجاد کنید:

    # Directory layout:
    #   my-project/
    #     firebase.json
    #     functions/
    #       .env
    #       package.json
    #       index.js
    
  2. فایل .env را برای ویرایش باز کرده و کلیدهای مورد نظر را اضافه کنید. به عنوان مثال:

    PLANET=Earth
    AUDIENCE=Humans
    
  3. توابع را مستقر کنید و بررسی کنید که متغیرهای محیط بارگذاری شده اند:

    firebase deploy --only functions
    # ...
    # i functions: Loaded environment variables from .env.
    # ...
    

هنگامی که متغیرهای محیط سفارشی شما مستقر شدند، کد تابع شما می تواند با دستور process.env به آنها دسترسی پیدا کند:

// Responds with "Hello Earth and Humans"
exports.hello = functions.https.onRequest((request, response) => {
  response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});

استقرار چندین مجموعه از متغیرهای محیطی

اگر به مجموعه‌ای از متغیرهای محیطی جایگزین برای پروژه‌های Firebase خود نیاز دارید (مانند مرحله‌بندی در مقابل تولید)، یک .env. <project or alias > را فایل کنید و متغیرهای محیطی خاص پروژه خود را در آنجا بنویسید. متغیرهای محیطی از .env و فایل‌های .env خاص پروژه (در صورت وجود) در همه توابع مستقر شده گنجانده می‌شوند.

به عنوان مثال، یک پروژه می تواند شامل این سه فایل باشد که حاوی مقادیر کمی متفاوت برای توسعه و تولید هستند:

.env .env.dev .env.prod
PLANET=زمین

AUDIENCE=انسان

AUDIENCE = Dev Humans AUDIENCE=انسان های تولیدکننده

با توجه به مقادیر موجود در آن فایل‌های جداگانه، مجموعه متغیرهای محیطی مستقر شده با توابع شما بسته به پروژه هدف شما متفاوت خواهد بود:

$ firebase use dev
$ firebase deploy --only functions
i functions: Loaded environment variables from .env, .env.dev.
# Deploys functions with following user-defined environment variables:
#   PLANET=Earth
#   AUDIENCE=Dev Humans

$ firebase use prod
$ firebase deploy --only functions
i functions: Loaded environment variables from .env, .env.prod.
# Deploys functions with following user-defined environment variables:
#   PLANET=Earth
#   AUDIENCE=Prod Humans

متغیرهای محیطی رزرو شده

برخی از کلیدهای متغیر محیطی برای استفاده داخلی رزرو شده اند. از هیچ یک از این کلیدها در فایل های .env خود استفاده نکنید:

  • همه کلیدها با X_GOOGLE_ شروع می شوند
  • شروع همه کلیدها EXT_
  • همه کلیدها با FIREBASE_ شروع می شوند
  • هر کلید از لیست زیر:
  • CLOUD_RUNTIME_CONFIG
  • ENTRY_POINT
  • GCP_PROJECT
  • GCLOUD_PROJECT
  • GOOGLE_CLOUD_PROJECT
  • FUNCTION_TRIGGER_TYPE
  • FUNCTION_NAME
  • FUNCTION_MEMORY_MB
  • FUNCTION_TIMEOUT_SEC
  • FUNCTION_IDENTITY
  • FUNCTION_REGION
  • FUNCTION_TARGET
  • FUNCTION_SIGNATURE_TYPE
  • K_SERVICE
  • K_REVISION
  • بندر
  • K_CONFIGURATION

ذخیره و دسترسی به اطلاعات پیکربندی حساس

متغیرهای محیطی ذخیره شده در فایل‌های .env می‌توانند برای پیکربندی عملکرد استفاده شوند، اما نباید آنها را راهی امن برای ذخیره اطلاعات حساس مانند اعتبار پایگاه داده یا کلیدهای API در نظر بگیرید. اگر فایل‌های .env خود را در کنترل منبع بررسی کنید، به ویژه مهم است.

برای کمک به ذخیره اطلاعات پیکربندی حساس، Cloud Functions for Firebase با Google Cloud Secret Manager ادغام می‌شود. این سرویس رمزگذاری شده مقادیر پیکربندی را به صورت ایمن ذخیره می کند، در حالی که همچنان در صورت نیاز امکان دسترسی آسان به عملکردهای شما را فراهم می کند.

یک راز ایجاد و استفاده کنید

برای ایجاد یک راز، از Firebase CLI استفاده کنید.

برای ایجاد و استفاده از یک راز:

  1. از ریشه دایرکتوری پروژه محلی خود، دستور زیر را اجرا کنید:

    firebase functions:secrets:set SECRET_NAME

  2. یک مقدار برای SECRET_NAME وارد کنید.

    CLI یک پیام موفقیت آمیز را بازتاب می دهد و هشدار می دهد که باید توابع را برای اعمال تغییر مستقر کنید.

  3. قبل از استقرار، مطمئن شوید که کد توابع شما به تابع اجازه می دهد تا با استفاده از پارامتر runWith به رمز دسترسی پیدا کند:

    exports.processPayment = functions
      // Make the secret available to this function
      .runWith({ secrets: ["SECRET_NAME"] })
      .onCall((data, context) => {
        const myBillingService = initializeBillingService(
          // reference the secret value
          process.env.SECRET_NAME
        );
        // Process the payment
      });
  4. استقرار Cloud Functions :

    firebase deploy --only functions

اکنون می توانید مانند سایر متغیرهای محیطی به آن دسترسی داشته باشید. برعکس، اگر تابع دیگری که در runWith رمز را مشخص نمی کند، سعی کند به Secret دسترسی پیدا کند، یک مقدار تعریف نشده دریافت می کند:

  exports.anotherEndpoint = functions.https.onRequest((request, response) => {
    response.send(`The secret API key is ${process.env.SECRET_NAME}`);
    // responds with "The secret API key is undefined" because the `runWith` parameter is missing
  });

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

مدیریت اسرار

از Firebase CLI برای مدیریت اسرار خود استفاده کنید. در حین مدیریت اسرار به این روش، به خاطر داشته باشید که برخی از تغییرات CLI شما را ملزم به تغییر و/یا استقرار مجدد توابع مرتبط می کند. به طور مشخص:

  • هر زمان که مقدار جدیدی را برای یک راز تنظیم می کنید، باید همه توابعی که به آن راز ارجاع می دهند را مجدداً به کار بگیرید تا آخرین مقدار را دریافت کنند.
  • اگر یک راز را حذف می کنید، مطمئن شوید که هیچ یک از توابع مستقر شما به آن راز ارجاع نمی دهد. توابعی که از یک مقدار مخفی استفاده می کنند که حذف شده است بی صدا از کار می افتند.

در اینجا خلاصه ای از دستورات Firebase CLI برای مدیریت مخفی آمده است:

# Change the value of an existing secret
firebase functions:secrets:set SECRET_NAME

# View the value of a secret
functions:secrets:access SECRET_NAME

# Destroy a secret
functions:secrets:destroy SECRET_NAME

# View all secret versions and their state
functions:secrets:get SECRET_NAME

# Automatically clean up all secrets that aren't referenced by any of your functions
functions:secrets:prune

برای دستورات access و destroy ، می توانید پارامتر نسخه اختیاری را برای مدیریت یک نسخه خاص ارائه دهید. به عنوان مثال:

functions:secrets:access SECRET_NAME[@VERSION]

برای اطلاعات بیشتر در مورد این عملیات، -h با دستور مشاهده راهنمای CLI عبور دهید.

اسرار چگونه صورتحساب می شوند

Secret Manager اجازه می دهد تا 6 نسخه مخفی فعال بدون هیچ هزینه ای. این بدان معنی است که شما می توانید 6 راز در هر ماه در پروژه Firebase بدون هیچ هزینه ای داشته باشید.

به‌طور پیش‌فرض، Firebase CLI تلاش می‌کند تا در صورت لزوم، نسخه‌های مخفی استفاده‌نشده را به‌طور خودکار از بین ببرد، مانند زمانی که توابع را با نسخه جدیدی از Secret مستقر می‌کنید. همچنین، می‌توانید اسرار بلااستفاده را با استفاده از functions:secrets:destroy و functions:secrets:prune به طور فعال پاکسازی کنید.

Secret Manager اجازه می دهد تا 10000 عملیات دسترسی ماهانه صورتحساب نشده در یک راز. نمونه های تابع، هر بار که سرد شروع می شوند، فقط اسرار مشخص شده در پارامتر runWith خود را می خوانند. اگر نمونه های عملکرد زیادی دارید که اسرار زیادی را می خوانند، ممکن است پروژه شما از این مقدار مجاز فراتر رود، در این مرحله به ازای هر 10000 عملیات دسترسی 0.03 دلار از شما دریافت می شود.

برای اطلاعات بیشتر، قیمت‌گذاری Secret Manager را ببینید.

پشتیبانی شبیه ساز

پیکربندی محیط با dotenv برای تعامل با یک شبیه ساز محلی Cloud Functions طراحی شده است.

هنگام استفاده از شبیه ساز Cloud Functions محلی، می توانید با تنظیم یک فایل .env.local ، متغیرهای محیط را برای پروژه خود لغو کنید. محتویات .env.local بر .env و فایل .env خاص پروژه اولویت دارند.

به عنوان مثال، یک پروژه می‌تواند شامل این سه فایل با مقادیر کمی متفاوت برای توسعه و آزمایش محلی باشد:

.env .env.dev .env.local
PLANET=زمین

AUDIENCE=انسان

AUDIENCE = Dev Humans AUDIENCE=انسان های محلی

هنگامی که در زمینه محلی شروع به کار کرد، شبیه ساز متغیرهای محیطی را همانطور که نشان داده شده بارگیری می کند:

  $ firebase emulators:start
  i  emulators: Starting emulators: functions
  # Starts emulator with following environment variables:
  #  PLANET=Earth
  #  AUDIENCE=Local Humans

اسرار و اعتبار در شبیه ساز Cloud Functions

شبیه ساز Cloud Functions از استفاده از اسرار برای ذخیره و دسترسی به اطلاعات پیکربندی حساس پشتیبانی می کند. به‌طور پیش‌فرض، شبیه‌ساز سعی می‌کند با استفاده از اعتبار پیش‌فرض برنامه به اسرار تولید شما دسترسی پیدا کند. در شرایط خاصی مانند محیط های CI، شبیه ساز ممکن است به دلیل محدودیت های مجوز، به مقادیر مخفی دسترسی پیدا نکند.

مشابه پشتیبانی شبیه ساز Cloud Functions برای متغیرهای محیطی، می توانید با تنظیم یک فایل .secret.local مقادیر مخفی را لغو کنید. این امر به شما امکان می دهد عملکردهای خود را به صورت محلی آزمایش کنید، به خصوص اگر به مقدار مخفی دسترسی ندارید.

مهاجرت از پیکربندی محیط

اگر از پیکربندی محیط با functions.config استفاده کرده اید، می توانید پیکربندی موجود خود را به عنوان متغیرهای محیطی (در قالب dotenv ) منتقل کنید. Firebase CLI یک فرمان صادراتی را ارائه می دهد که پیکربندی هر نام مستعار یا پروژه فهرست شده در فایل .firebaserc دایرکتوری شما (در مثال زیر، local ، dev و prod ) را به عنوان فایل های .env .

برای انتقال، تنظیمات محیط موجود خود را با استفاده از دستور firebase functions:config:export کنید:

firebase functions:config:export
i  Importing configs from projects: [project-0, project-1]
⚠  The following configs keys could not be exported as environment variables:

⚠  project-0 (dev):
    1foo.a => 1FOO\_A (Key 1FOO\_A must start with an uppercase ASCII letter or underscore, and then consist of uppercase ASCII letters, digits, and underscores.)

Enter a PREFIX to rename invalid environment variable keys: CONFIG\_
✔  Wrote functions/.env.prod
✔  Wrote functions/.env.dev
✔  Wrote functions/.env.local
✔  Wrote functions/.env

توجه داشته باشید که در برخی موارد، از شما خواسته می شود که یک پیشوند برای تغییر نام کلیدهای متغیر محیطی صادر شده وارد کنید. این به این دلیل است که همه پیکربندی ها را نمی توان به طور خودکار تغییر داد زیرا ممکن است نامعتبر باشند یا ممکن است یک کلید متغیر محیطی رزرو شده باشند.

توصیه می کنیم قبل از استقرار توابع خود یا بررسی فایل های .env در کنترل منبع، محتویات فایل های .env تولید شده را به دقت بررسی کنید. اگر مقادیری حساس هستند و نباید فاش شوند، آن‌ها را از فایل‌های .env خود حذف کرده و به‌جای آن به‌طور ایمن در Secret Manager ذخیره کنید.

همچنین باید کد توابع خود را به روز کنید. هر تابعی که از functions.config استفاده می کند، اکنون باید به جای آن از process.env استفاده کند، همانطور که در ارتقا به نسل دوم نشان داده شده است.

پیکربندی محیط

تنظیمات محیط را با CLI تنظیم کنید

برای ذخیره داده های محیطی، می توانید از فرمان firebase functions:config:set در Firebase CLI استفاده کنید. هر کلید را می‌توان با استفاده از نقطه‌ها برای گروه‌بندی پیکربندی‌های مرتبط با یکدیگر، در فضای نام قرار داد. به خاطر داشته باشید که فقط حروف کوچک در کلیدها پذیرفته می شوند . حروف بزرگ مجاز نیستند.

به عنوان مثال، برای ذخیره شناسه مشتری و کلید API برای "Some Service"، ممکن است اجرا کنید:

firebase functions:config:set someservice.key="THE API KEY" someservice.id="THE CLIENT ID"

پیکربندی محیط فعلی را بازیابی کنید

برای بررسی آنچه در حال حاضر در پیکربندی محیط برای پروژه شما ذخیره شده است، می توانید firebase functions:config:get استفاده کنید. خروجی JSON چیزی شبیه به این است:

{
  "someservice": {
    "key":"THE API KEY",
    "id":"THE CLIENT ID"
  }
}

این عملکرد بر اساس Google Cloud Runtime Configuration API است.

از functions.config برای دسترسی به پیکربندی محیط در یک تابع استفاده کنید

برخی از تنظیمات به طور خودکار در فضای نام firebase رزرو شده ارائه می شود. پیکربندی محیط در داخل تابع در حال اجرا از طریق functions.config() در دسترس است. برای استفاده از پیکربندی بالا، کد شما ممکن است به شکل زیر باشد:

const functions = require('firebase-functions/v1');
const request = require('request-promise');

exports.userCreated = functions.database.ref('/users/{id}').onWrite(event => {
  let email = event.data.child('email').val();

  return request({
    url: 'https://someservice.com/api/some/call',
    headers: {
      'X-Client-ID': functions.config().someservice.id,
      'Authorization': `Bearer ${functions.config().someservice.key}`
    },
    body: {email: email}
  });
});

از پیکربندی محیط برای مقداردهی اولیه یک ماژول استفاده کنید

برخی از ماژول های Node بدون هیچ گونه پیکربندی آماده هستند. ماژول‌های دیگر برای تنظیم اولیه به تنظیمات بیشتری نیاز دارند. توصیه می کنیم این پیکربندی را به جای کدگذاری سخت، در متغیرهای پیکربندی محیط ذخیره کنید. این به شما کمک می کند تا کد خود را بسیار قابل حمل تر نگه دارید، که به شما امکان می دهد برنامه خود را منبع باز کنید یا به راحتی بین نسخه های تولیدی و مرحله بندی جابجا شوید.

به عنوان مثال، برای استفاده از ماژول Slack Node SDK ، ممکن است این را بنویسید:

const functions = require('firebase-functions/v1');
const IncomingWebhook = require('@slack/client').IncomingWebhook;
const webhook = new IncomingWebhook(functions.config().slack.url);

قبل از استقرار، متغیر پیکربندی محیط slack.url را تنظیم کنید:

firebase functions:config:set slack.url=https://hooks.slack.com/services/XXX

دستورات محیطی اضافی

  • firebase functions:config:unset key1 key2 کلیدهای مشخص شده را از پیکربندی حذف می کند
  • firebase functions:config:clone --from <fromProject> محیط پروژه دیگری را در پروژه فعال فعلی شبیه سازی می کند.

متغیرهای محیطی به طور خودکار پر می شوند

متغیرهای محیطی وجود دارند که به طور خودکار در زمان اجرا توابع و توابع شبیه سازی شده محلی پر می شوند. اینها شامل مواردی است که توسط Google Cloud و همچنین یک متغیر محیطی خاص Firebase وجود دارد :

process.env.FIREBASE_CONFIG : اطلاعات پیکربندی پروژه Firebase زیر را ارائه می دهد:

{
  databaseURL: 'https://DATABASE_NAME.firebaseio.com',
  storageBucket: 'PROJECT_ID.firebasestorage.app',
  projectId: 'PROJECT_ID'
}

توجه داشته باشید که مقادیر موجود در پیکربندی Firebase واقعی شما ممکن است بسته به منابعی که در پروژه خود تهیه کرده اید متفاوت باشد.

هنگامی که Firebase Admin SDK را بدون آرگومان مقداردهی کنید، این پیکربندی به طور خودکار اعمال می شود. اگر در حال نوشتن توابع در جاوا اسکریپت هستید، به صورت زیر مقداردهی اولیه کنید:

const admin = require('firebase-admin');
admin.initializeApp();

اگر توابع را در TypeScript می نویسید، به صورت زیر مقداردهی اولیه کنید:

import * as functions from 'firebase-functions/v1';
import * as admin from 'firebase-admin';
import 'firebase-functions/v1';
admin.initializeApp();

اگر نیاز دارید Admin SDK را با پیکربندی پروژه پیش‌فرض با استفاده از اعتبار حساب سرویس، مقداردهی اولیه کنید، می‌توانید اعتبارنامه‌ها را از یک فایل بارگیری کنید و آنها را به FIREBASE_CONFIG به این صورت اضافه کنید:

serviceAccount = require('./serviceAccount.json');

const adminConfig = JSON.parse(process.env.FIREBASE_CONFIG);
adminConfig.credential = admin.credential.cert(serviceAccount);
admin.initializeApp(adminConfig);
،


اغلب برای عملکردهای خود به پیکربندی اضافی نیاز دارید، مانند کلیدهای API شخص ثالث یا تنظیمات قابل تنظیم. Firebase SDK for Cloud Functions پیکربندی محیط داخلی را ارائه می دهد تا ذخیره و بازیابی این نوع داده ها را برای پروژه شما آسان کند.

می توانید بین این گزینه ها یکی را انتخاب کنید:

  • پیکربندی پارامتری (برای اکثر سناریوها توصیه می شود). این پیکربندی محیطی با تایپ قوی با پارامترهایی را فراهم می کند که در زمان استقرار تأیید می شوند، که از خطاها جلوگیری می کند و اشکال زدایی را ساده می کند.
  • پیکربندی مبتنی بر فایل متغیرهای محیطی . با این روش، شما به صورت دستی یک فایل dotenv برای بارگیری متغیرهای محیطی ایجاد می کنید.

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

پیکربندی پارامتری شده

Cloud Functions for Firebase یک رابط برای تعریف پارامترهای پیکربندی به صورت اعلامی در پایگاه کد شما فراهم می کند. مقدار این پارامترها هم در حین استقرار تابع، هم هنگام تنظیم گزینه های استقرار و زمان اجرا و هم در حین اجرا در دسترس است. این بدان معنی است که CLI استقرار را مسدود می کند مگر اینکه همه پارامترها دارای یک مقدار معتبر باشند.

برای تعریف پارامترها در کد خود ، این مدل را دنبال کنید:

const functions = require('firebase-functions/v1');
const { defineInt, defineString } = require('firebase-functions/params');

// Define some parameters
const minInstancesConfig = defineInt('HELLO_WORLD_MININSTANCES');
const welcomeMessage = defineString('WELCOME_MESSAGE');

// To use configured parameters inside the config for a function, provide them
// directly. To use them at runtime, call .value() on them.
export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
  (req, res) => {
    res.send(`${welcomeMessage.value()}! I am a function.`);
  }
);

هنگام استقرار یک تابع با متغیرهای پیکربندی پارامتری ، Firebase CLI ابتدا سعی می کند مقادیر خود را از پرونده های محلی .ENV بارگیری کند. اگر آنها در آن پرونده ها حضور نداشته باشند و هیچ default تنظیم نشده باشد ، CLI مقادیر را در هنگام استقرار فوری می کند و سپس به طور خودکار مقادیر خود functions/ در یک پرونده .env به نام .env.<project_ID>

$ firebase deploy
i  functions: preparing codebase default for deployment
? Enter a string value for ENVIRONMENT: prod
i  functions: Writing new parameter values to disk: .env.projectId
…
$ firebase deploy
i  functions: Loaded environment variables from .env.projectId

بسته به گردش کار توسعه شما ، ممکن است اضافه کردن پرونده تولید شده .env.<project_ID> به کنترل نسخه مفید باشد.

با استفاده از پارامترها در دامنه جهانی

در حین استقرار ، قبل از اینکه پارامترهای شما مقادیر واقعی داشته باشند ، کد توابع شما بارگیری و بازرسی می شود. این بدان معنی است که مقادیر پارامتر واکشی در طول دامنه جهانی منجر به خرابی استقرار می شود. برای مواردی که می خواهید از یک پارامتر برای اولیه سازی یک مقدار جهانی استفاده کنید ، از onInit() . این پاسخ به تماس قبل از اجرای هرگونه کارکرد در تولید اجرا می شود اما در زمان استقرار فراخوانی نمی شود ، بنابراین یک مکان امن برای دسترسی به مقدار پارامتر است.

  const { GoogleGenerativeAI } = require('@google/generative-ai');
  const { defineSecret } = require('firebase-functions/params');
  const { onInit } = require('firebase-functions/v1');

  const apiKey = defineSecret('GOOGLE_API_KEY');

  let genAI;
  onInit(() => {
    genAI = new GoogleGenerativeAI(apiKey.value());
  })

رفتار CLI را پیکربندی کنید

پارامترها را می توان با یک شیء Options پیکربندی کرد که کنترل می کند که چگونه CLI برای مقادیر فوری می کند. مثال زیر گزینه هایی را برای اعتبارسنجی قالب یک شماره تلفن ، ارائه یک گزینه انتخاب ساده و جمع آوری یک گزینه انتخاب به طور خودکار از پروژه Firebase تنظیم می کند:

const { defineString } = require('firebase-functions/params');

const welcomeMessage = defineString('WELCOME_MESSAGE', {default: 'Hello World',
description: 'The greeting that is returned to the caller of this function'});

const onlyPhoneNumbers = defineString('PHONE_NUMBER', {input: {text:
{validationRegex: /\d{3}-\d{3}-\d{4}/, validationErrorMessage: "Please enter
a phone number in the format XXX-YYY-ZZZZ"}}});

const selectedOption = defineString('PARITY', {input: {select: {options:
[{value: "odd"}, {value: "even"}]}}})

const storageBucket = defineString('BUCKET', {input: {resource: {type:
"storage.googleapis.com/Bucket"}}, description: "This will automatically
populate the selector field with the deploying Cloud Project’s
storage buckets"})

انواع پارامترها

پیکربندی پارامتری تایپ قوی برای مقادیر پارامتر ، و همچنین از اسرار از Cloud Secret Manager پشتیبانی می کند. انواع پشتیبانی شده عبارتند از:

  • راز
  • رشته
  • بولی
  • عدد صحیح
  • شناور

مقادیر و عبارات پارامتر

Firebase پارامترهای شما را هم در زمان استقرار ارزیابی می کند و در حالی که عملکرد شما در حال اجرا است. با توجه به این محیط های دوتایی ، هنگام مقایسه مقادیر پارامتر ، باید مراقبت های اضافی انجام شود و هنگام استفاده از آنها برای تنظیم گزینه های زمان اجرا برای عملکردهای خود.

برای انتقال یک پارامتر به عملکرد خود به عنوان گزینه زمان اجرا ، مستقیماً آن را منتقل کنید:

const functions = require('firebase-functions/v1');
const { defineInt} = require('firebase-functions/params');
const minInstancesConfig = defineInt('HELLO\_WORLD\_MININSTANCES');

export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
  (req, res) => {
    //…

علاوه بر این ، اگر شما نیاز به مقایسه در برابر یک پارامتر دارید تا بدانید چه گزینه ای را انتخاب کنید ، به جای بررسی مقدار باید از مقایسه کننده های داخلی استفاده کنید:

const functions = require('firebase-functions/v1');
const { defineBool } = require('firebase-functions/params');
const environment = params.defineString(ENVIRONMENT, {default: dev});

// use built-in comparators
const minInstancesConfig =environment.equals('PRODUCTION').thenElse(10, 1);
export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
  (req, res) => {
    //…

پارامترها و عبارات پارامتری که فقط در زمان اجرا استفاده می شوند با عملکرد value آنها قابل دسترسی هستند:

const functions = require('firebase-functions/v1');
const { defineString } = require('firebase-functions/params');
const welcomeMessage = defineString('WELCOME_MESSAGE');

// To use configured parameters inside the config for a function, provide them
// directly. To use them at runtime, call .value() on them.
export const helloWorld = functions.https.onRequest(
 (req, res) => {
    res.send(`${welcomeMessage.value()}! I am a function.`);
  }
);

پارامترهای داخلی

توابع Cloud SDK سه پارامتر از پیش تعریف شده را ارائه می دهد ، که از زیر بسته های firebase-functions/params موجود است:

  • projectID - پروژه ابری که عملکرد در آن اجرا می شود.
  • databaseURL - URL نمونه پایگاه داده Realtime مرتبط با عملکرد (در صورت فعال بودن در پروژه Firebase).
  • storageBucket - سطل ذخیره سازی ابر مرتبط با عملکرد (در صورت فعال بودن در پروژه Firebase).

این عملکرد مانند پارامترهای رشته ای تعریف شده توسط کاربر از هر نظر ، به جز این که ، از آنجا که مقادیر آنها همیشه به CLI Firebase شناخته می شود ، مقادیر آنها هرگز از استقرار و ذخیره در پرونده های .env خواسته نمی شود.

پارامترهای مخفی

پارامترهای نوع Secret ، تعریف شده با استفاده از defineSecret() ، پارامترهای رشته ای را نشان می دهد که دارای مقدار ذخیره شده در Cloud Secret Manager هستند. به جای بررسی در برابر پرونده محلی .env و نوشتن یک مقدار جدید در صورت گم شدن ، پارامترهای مخفی در برابر وجود در Cloud Secret Manager بررسی می کنند و به طور تعاملی ارزش یک راز جدید را در هنگام استقرار سریع می کنند.

پارامترهای مخفی تعریف شده از این طریق باید به توابع فردی که باید به آنها دسترسی داشته باشند ، محدود شود:

const functions = require('firebase-functions/v1');
const { defineSecret } = require('firebase-functions/params');
const discordApiKey = defineSecret('DISCORD_API_KEY');

export const postToDiscord = functions.runWith({ secrets: [discordApiKey] }).https.onRequest(
  (req, res) => {
    const apiKey = discordApiKey.value();
    //…

از آنجا که مقادیر اسرار تا زمان اجرای عملکرد پنهان است ، شما نمی توانید ضمن پیکربندی عملکرد خود از آنها استفاده کنید.

متغیرهای محیطی

Cloud Functions for Firebase از فرمت پرونده dotenv برای بارگیری متغیرهای محیط مشخص شده در یک پرونده .env به زمان اجرا برنامه شما پشتیبانی می کند. پس از استقرار ، متغیرهای محیط را می توان از طریق رابط process.env خواند.

برای پیکربندی محیط خود از این طریق ، یک فایل .env را در پروژه خود ایجاد کنید ، متغیرهای مورد نظر را اضافه کرده و مستقر کنید:

  1. یک فایل .env را در functions/ فهرست خود ایجاد کنید:

    # Directory layout:
    #   my-project/
    #     firebase.json
    #     functions/
    #       .env
    #       package.json
    #       index.js
    
  2. پرونده .env را برای ویرایش باز کنید و کلیدهای مورد نظر را اضافه کنید. به عنوان مثال:

    PLANET=Earth
    AUDIENCE=Humans
    
  3. توابع را مستقر کنید و تأیید کنید که متغیرهای محیط بارگیری شده اند:

    firebase deploy --only functions
    # ...
    # i functions: Loaded environment variables from .env.
    # ...
    

پس از استقرار متغیرهای محیط سفارشی شما ، کد عملکرد شما می تواند با process.env PROCESS.ENV به آنها دسترسی پیدا کند:

// Responds with "Hello Earth and Humans"
exports.hello = functions.https.onRequest((request, response) => {
  response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});

استفاده از چندین مجموعه از متغیرهای محیط

اگر برای پروژه های Firebase خود (مانند مرحله بندی در مقابل تولید) به مجموعه متغیرهای محیط زیست نیاز دارید ، ایجاد یک .env. <project or alias > پرونده را بنویسید و متغیرهای محیط خاص پروژه خود را در آنجا بنویسید. متغیرهای محیط از پرونده های .env و پروژه های خاص .env (در صورت وجود) در کلیه عملکردهای مستقر گنجانده می شوند.

به عنوان مثال ، یک پروژه می تواند شامل این سه پرونده باشد که حاوی مقادیر کمی متفاوت برای توسعه و تولید است:

.env .env.dev .env.prod
سیاره = زمین

مخاطب = انسان

مخاطب = انسانهای دیو مخاطب = انسانها

با توجه به مقادیر موجود در این پرونده های جداگانه ، مجموعه متغیرهای محیط مستقر شده با کارکردهای شما بسته به پروژه هدف شما متفاوت خواهد بود:

$ firebase use dev
$ firebase deploy --only functions
i functions: Loaded environment variables from .env, .env.dev.
# Deploys functions with following user-defined environment variables:
#   PLANET=Earth
#   AUDIENCE=Dev Humans

$ firebase use prod
$ firebase deploy --only functions
i functions: Loaded environment variables from .env, .env.prod.
# Deploys functions with following user-defined environment variables:
#   PLANET=Earth
#   AUDIENCE=Prod Humans

متغیرهای محیطی رزرو شده

برخی از کلیدهای متغیر محیط برای استفاده داخلی محفوظ هستند. از هیچ یک از این کلیدها در پرونده های .env خود استفاده نکنید:

  • همه کلیدها با X_Google_ شروع می شوند
  • همه کلیدها شروع به ext_
  • تمام کلیدها با Firebase_ شروع می شوند
  • هر کلید از لیست زیر:
  • cloud_runtime_config
  • نقطه ورود_
  • gcp_project
  • gcloud_project
  • google_cloud_project
  • function_trigger_type
  • contion_name
  • function_memory_mb
  • function_timeout_sec
  • عملکرد_آیدیت
  • function_rebion
  • تابع
  • function_signature_type
  • K_SERVICE
  • K_REVISION
  • بندر
  • K_CONFIGURATION

اطلاعات پیکربندی حساس را ذخیره و دسترسی پیدا کنید

متغیرهای محیطی ذخیره شده در پرونده های .env می توانند برای پیکربندی عملکرد استفاده شوند ، اما شما نباید آنها را یک روش مطمئن برای ذخیره اطلاعات حساس مانند اعتبار پایگاه داده یا کلیدهای API در نظر بگیرید. این امر به ویژه در صورتی که پرونده های .env خود را در کنترل منبع بررسی کنید ، بسیار مهم است.

برای کمک به شما در ذخیره اطلاعات پیکربندی حساس ، Cloud Functions for Firebase با Google Cloud Secret Manager ادغام می شود. این سرویس رمزگذاری شده مقادیر پیکربندی را به طور ایمن ذخیره می کند ، در حالی که در صورت لزوم امکان دسترسی آسان از توابع شما را فراهم می کند.

ایجاد و استفاده از یک راز

برای ایجاد یک راز ، از Firebase CLI استفاده کنید.

برای ایجاد و استفاده از یک راز:

  1. از ریشه دایرکتوری پروژه محلی خود ، دستور زیر را اجرا کنید:

    firebase functions:secrets:set SECRET_NAME

  2. یک مقدار برای SECRET_NAME وارد کنید.

    CLI یک پیام موفقیت آمیز را تکرار می کند و هشدار می دهد که شما باید توابع خود را برای تغییر اعمال کنید.

  3. قبل از استقرار ، اطمینان حاصل کنید که کد توابع شما با استفاده از پارامتر runWith به عملکرد اجازه می دهد تا به راز دسترسی پیدا کند:

    exports.processPayment = functions
      // Make the secret available to this function
      .runWith({ secrets: ["SECRET_NAME"] })
      .onCall((data, context) => {
        const myBillingService = initializeBillingService(
          // reference the secret value
          process.env.SECRET_NAME
        );
        // Process the payment
      });
  4. Cloud Functions را مستقر کنید:

    firebase deploy --only functions

اکنون می توانید مانند هر متغیر محیط دیگر به آن دسترسی پیدا کنید. برعکس ، اگر عملکرد دیگری که راز را در runWith مشخص نمی کند ، سعی در دسترسی به راز دارد ، یک مقدار نامشخص دریافت می کند:

  exports.anotherEndpoint = functions.https.onRequest((request, response) => {
    response.send(`The secret API key is ${process.env.SECRET_NAME}`);
    // responds with "The secret API key is undefined" because the `runWith` parameter is missing
  });

پس از استقرار عملکرد شما ، به مقدار مخفی دسترسی خواهد داشت. فقط کارکردهایی که به طور خاص شامل یک راز در پارامتر runWith خود هستند ، به عنوان یک متغیر محیط به آن راز دسترسی دارند. این به شما کمک می کند تا اطمینان حاصل کنید که مقادیر مخفی فقط در صورت نیاز در دسترس هستند و خطر نشت تصادفی راز را کاهش می دهد.

مدیریت اسرار

برای مدیریت اسرار خود از Firebase CLI استفاده کنید. در حین مدیریت اسرار از این طریق ، به خاطر داشته باشید که برخی از تغییرات CLI شما را ملزم به اصلاح و/یا مجدداً کارکردهای مرتبط با آن می کند. به طور مشخص:

  • هر زمان که مقدار جدیدی را برای یک راز تعیین کنید ، باید کلیه کارکردهایی را که برای آنها راز است برای انتخاب آخرین ارزش ، مجدداً استفاده کنید.
  • اگر یک راز را حذف کردید ، اطمینان حاصل کنید که هیچ یک از کارکردهای مستقر شما به آن راز مراجعه نمی کنند. کارکردهایی که از یک مقدار مخفی استفاده می کنند که حذف شده است ، سکوت شکست می خورند.

در اینجا خلاصه ای از دستورات CLI Firebase برای مدیریت مخفی وجود دارد:

# Change the value of an existing secret
firebase functions:secrets:set SECRET_NAME

# View the value of a secret
functions:secrets:access SECRET_NAME

# Destroy a secret
functions:secrets:destroy SECRET_NAME

# View all secret versions and their state
functions:secrets:get SECRET_NAME

# Automatically clean up all secrets that aren't referenced by any of your functions
functions:secrets:prune

برای دستورات access و destroy ، می توانید پارامتر نسخه اختیاری را برای مدیریت یک نسخه خاص ارائه دهید. به عنوان مثال:

functions:secrets:access SECRET_NAME[@VERSION]

برای کسب اطلاعات بیشتر در مورد این عملیات ، با فرمان برای مشاهده کمک CLI ، -h کنید.

چگونه اسرار صورتحساب می شود

Secret Manager اجازه می دهد 6 نسخه مخفی فعال و بدون هزینه. این بدان معنی است که شما می توانید 6 راز در هر ماه در یک پروژه Firebase بدون هیچ هزینه ای داشته باشید.

به طور پیش فرض ، Firebase CLI سعی می کند در صورت لزوم نسخه های مخفی بلااستفاده را به طور خودکار از بین ببرد ، مانند هنگام استقرار توابع با نسخه جدید راز. همچنین ، شما می توانید اسرار استفاده نشده را با استفاده از functions:secrets:destroy و functions:secrets:prune .

Secret Manager اجازه می دهد تا 10،000 عملیات دسترسی ماهانه Uncilly را در یک راز انجام دهد. نمونه های عملکرد فقط اسرار مشخص شده در پارامتر runWith خود را هر بار که شروع می کنند ، می خوانند. اگر نمونه های عملکرد زیادی در حال خواندن اسرار زیادی دارید ، پروژه شما ممکن است از این کمک هزینه فراتر رود ، در این مرحله 0.03 دلار در هر 10،000 عملیات دسترسی به شما پرداخت می شود.

برای اطلاعات بیشتر ، به قیمت گذاری Secret Manager مراجعه کنید.

پشتیبانی شبیه ساز

پیکربندی محیط با DotENV برای تعامل با یک شبیه ساز Cloud Functions محلی طراحی شده است.

هنگام استفاده از یک شبیه ساز Cloud Functions Cloud ، می توانید با تنظیم یک پرونده .env.local متغیرهای محیط را برای پروژه خود نادیده بگیرید. محتویات .env.local بر پرونده .env و پرونده خاص .env .

به عنوان مثال ، یک پروژه می تواند شامل این سه پرونده باشد که حاوی مقادیر کمی متفاوت برای توسعه و آزمایش محلی است:

.env .env.dev .env.local
سیاره = زمین

مخاطب = انسان

مخاطب = انسانهای دیو مخاطب = انسانهای محلی

هنگامی که در متن محلی شروع شد ، شبیه ساز متغیرهای محیط را همانطور که نشان داده شده است ، بارگذاری می کند:

  $ firebase emulators:start
  i  emulators: Starting emulators: functions
  # Starts emulator with following environment variables:
  #  PLANET=Earth
  #  AUDIENCE=Local Humans

اسرار و اعتبار در شبیه ساز Cloud Functions

شبیه ساز Cloud Functions از استفاده از اسرار برای ذخیره و دسترسی به اطلاعات پیکربندی حساس پشتیبانی می کند. به طور پیش فرض ، شبیه ساز سعی خواهد کرد با استفاده از اعتبار پیش فرض برنامه ، به اسرار تولید شما دسترسی پیدا کند. در شرایط خاصی مانند محیط های CI ، شبیه ساز به دلیل محدودیت اجازه ممکن است به مقادیر مخفی دسترسی پیدا کند.

مشابه پشتیبانی Cloud Functions Trains برای متغیرهای محیط ، می توانید با تنظیم یک پرونده .secret.local مقادیر اسرار را نادیده بگیرید. این کار آزمایشات خود را به صورت محلی برای شما آسان می کند ، به خصوص اگر به مقدار مخفی دسترسی ندارید.

مهاجرت از پیکربندی محیط

اگر از پیکربندی محیط با functions.config استفاده کرده اید ، می توانید پیکربندی موجود خود را به عنوان متغیرهای محیط (با فرمت dotenv ) مهاجرت کنید. Firebase CLI یک دستور صادراتی را ارائه می دهد که پیکربندی هر نام مستعار یا پروژه ذکر شده در پرونده شما .firebaserc (در مثال زیر ، local ، dev و prod ) را به عنوان پرونده های .env وارد می کند.

برای مهاجرت ، تنظیمات محیط موجود خود را با استفاده از firebase functions:config:export :

firebase functions:config:export
i  Importing configs from projects: [project-0, project-1]
⚠  The following configs keys could not be exported as environment variables:

⚠  project-0 (dev):
    1foo.a => 1FOO\_A (Key 1FOO\_A must start with an uppercase ASCII letter or underscore, and then consist of uppercase ASCII letters, digits, and underscores.)

Enter a PREFIX to rename invalid environment variable keys: CONFIG\_
✔  Wrote functions/.env.prod
✔  Wrote functions/.env.dev
✔  Wrote functions/.env.local
✔  Wrote functions/.env

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

توصیه می کنیم قبل از استقرار توابع خود .env محتوای پرونده های تولید شده را با دقت بررسی کنید یا پرونده های .env را در کنترل منبع بررسی کنید. اگر مقادیر حساس هستند و نباید فاش شوند ، آنها را از پرونده های .env خود حذف کرده و به جای آن ، آنها را به طور ایمن در Secret Manager ذخیره کنید.

همچنین باید کد توابع خود را به روز کنید. هر کارکردی که از functions.config استفاده می کنند. config اکنون باید به جای آن از process.env استفاده کند ، همانطور که در ارتقاء به Gen 2 نشان داده شده است.

پیکربندی محیط

تنظیمات محیط را با CLI تنظیم کنید

برای ذخیره داده های محیط ، می توانید firebase functions:config:set فرمان را در Firebase CLI تنظیم کنید. هر کلید را می توان با استفاده از دوره هایی برای پیکربندی مرتبط با گروه با هم نامگذاری کرد. به خاطر داشته باشید که فقط شخصیت های کوچک در کلیدها پذیرفته می شوند . شخصیت های بزرگ مجاز نیستند.

به عنوان مثال ، برای ذخیره شناسه مشتری و کلید API برای "برخی از خدمات" ، ممکن است اجرا کنید:

firebase functions:config:set someservice.key="THE API KEY" someservice.id="THE CLIENT ID"

پیکربندی محیط فعلی را بازیابی کنید

برای بازرسی از آنچه در حال حاضر در پیکربندی محیط برای پروژه خود ذخیره شده است ، می توانید firebase functions:config:get . این JSON چیزی شبیه به این را تولید می کند:

{
  "someservice": {
    "key":"THE API KEY",
    "id":"THE CLIENT ID"
  }
}

این قابلیت مبتنی بر API پیکربندی زمان اجرا Google Cloud است.

برای دسترسی به پیکربندی محیط در یک تابع functions.config استفاده کنید.

برخی از پیکربندی ها به طور خودکار در فضای نام خانوادگی firebase ارائه می شود. پیکربندی محیط در داخل عملکرد شما از طریق functions.config() . برای استفاده از پیکربندی بالا ، کد شما ممکن است به این شکل باشد:

const functions = require('firebase-functions/v1');
const request = require('request-promise');

exports.userCreated = functions.database.ref('/users/{id}').onWrite(event => {
  let email = event.data.child('email').val();

  return request({
    url: 'https://someservice.com/api/some/call',
    headers: {
      'X-Client-ID': functions.config().someservice.id,
      'Authorization': `Bearer ${functions.config().someservice.key}`
    },
    body: {email: email}
  });
});

از پیکربندی محیط برای اولیه سازی یک ماژول استفاده کنید

برخی از ماژول های گره بدون هیچ پیکربندی آماده هستند. ماژول های دیگر برای تنظیم صحیح به پیکربندی اضافی نیاز دارند. توصیه می کنیم این پیکربندی را در متغیرهای پیکربندی محیط به جای کدگذاری سخت آن ذخیره کنید. این به شما کمک می کند تا کد خود را بسیار قابل حمل تر نگه دارید ، که به شما امکان می دهد منبع باز برنامه خود را باز کنید یا به راحتی بین نسخه های تولید و مرحله بندی جابجا شوید.

به عنوان مثال ، برای استفاده از ماژول Slack Node SDK ، ممکن است این را بنویسید:

const functions = require('firebase-functions/v1');
const IncomingWebhook = require('@slack/client').IncomingWebhook;
const webhook = new IncomingWebhook(functions.config().slack.url);

قبل از استقرار ، متغیر پیکربندی محیط slack.url را تنظیم کنید:

firebase functions:config:set slack.url=https://hooks.slack.com/services/XXX

دستورات محیط اضافی

  • firebase functions:config:unset key1 key2 کلیدهای مشخص شده را از پیکربندی حذف می کند
  • firebase functions:config:clone --from <fromProject> محیط یک پروژه دیگر را به پروژه فعال فعلی تبدیل کرد.

متغیرهای محیطی پرجمعیت

متغیرهای محیطی وجود دارد که به طور خودکار در توابع زمان اجرا و در توابع شبیه سازی شده محلی جمع می شوند. این موارد شامل مواردی است که توسط Google Cloud و همچنین یک متغیر محیطی خاص Firebase وجود دارد :

process.env.FIREBASE_CONFIG : اطلاعات پیکربندی پروژه Firebase زیر را ارائه می دهد:

{
  databaseURL: 'https://DATABASE_NAME.firebaseio.com',
  storageBucket: 'PROJECT_ID.firebasestorage.app',
  projectId: 'PROJECT_ID'
}

توجه داشته باشید که مقادیر موجود در پیکربندی واقعی Firebase ممکن است بسته به منابعی که در پروژه خود ارائه داده اید متفاوت باشد.

این پیکربندی به طور خودکار هنگام تنظیم اولیه SDK Admin Firebase بدون هیچ استدلالی اعمال می شود. اگر در JavaScript توابع خود را می نویسید ، مانند این اولیه کنید:

const admin = require('firebase-admin');
admin.initializeApp();

اگر در حال نوشتن توابع در TypeScript هستید ، مانند این اولیه باشید:

import * as functions from 'firebase-functions/v1';
import * as admin from 'firebase-admin';
import 'firebase-functions/v1';
admin.initializeApp();

اگر نیاز به تنظیم SDK Admin با پیکربندی پیش فرض پروژه با استفاده از اعتبارنامه حساب خدمات دارید ، می توانید اعتبارنامه ها را از یک پرونده بارگیری کرده و مانند این به FIREBASE_CONFIG اضافه کنید:

serviceAccount = require('./serviceAccount.json');

const adminConfig = JSON.parse(process.env.FIREBASE_CONFIG);
adminConfig.credential = admin.credential.cert(serviceAccount);
admin.initializeApp(adminConfig);
،


اغلب برای کارکردهای خود مانند کلیدهای API شخص ثالث یا تنظیمات قابل تنظیم به پیکربندی اضافی نیاز دارید. Firebase SDK for Cloud Functions پیکربندی محیط داخلی را ارائه می دهد تا ذخیره و بازیابی این نوع داده ها را برای پروژه خود آسان کند.

می توانید بین این گزینه ها انتخاب کنید:

  • پیکربندی پارامتری (برای اکثر سناریوها توصیه می شود). این پیکربندی محیط به شدت تایپ شده با پارامترهایی که در زمان استقرار تأیید می شوند ، فراهم می کند ، که از خطاها جلوگیری می کند و اشکال زدایی را ساده می کند.
  • پیکربندی مبتنی بر پرونده متغیرهای محیط . با این رویکرد ، شما به صورت دستی یک فایل dotenv برای بارگیری متغیرهای محیط ایجاد می کنید.

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

پیکربندی پارامتری

Cloud Functions for Firebase رابط کاربری برای تعریف پارامترهای پیکربندی به صورت اعلامیه ای در قسمت کد شما فراهم می کند. مقدار این پارامترها هم در هنگام استقرار و هم در تنظیم گزینه های استقرار و زمان اجرا و در حین اجرای ، هم در طول استقرار عملکرد در دسترس است. این بدان معنی است که CLI استقرار را مسدود می کند مگر اینکه همه پارامترها دارای یک مقدار معتبر باشند.

To define parameters in your code, follow this model:

const functions = require('firebase-functions/v1');
const { defineInt, defineString } = require('firebase-functions/params');

// Define some parameters
const minInstancesConfig = defineInt('HELLO_WORLD_MININSTANCES');
const welcomeMessage = defineString('WELCOME_MESSAGE');

// To use configured parameters inside the config for a function, provide them
// directly. To use them at runtime, call .value() on them.
export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
  (req, res) => {
    res.send(`${welcomeMessage.value()}! I am a function.`);
  }
);

When deploying a function with parameterized configuration variables, the Firebase CLI first attempts to load their values from local .env files. If they are not present in those files and no default is set, the CLI will prompt for the values during deployment, and then automatically save their values to a .env file named .env.<project_ID> in your functions/ directory:

$ firebase deploy
i  functions: preparing codebase default for deployment
? Enter a string value for ENVIRONMENT: prod
i  functions: Writing new parameter values to disk: .env.projectId
…
$ firebase deploy
i  functions: Loaded environment variables from .env.projectId

Depending on your development workflow, it may be useful to add the generated .env.<project_ID> file to version control.

Using parameters in global scope

During deployment, your functions code is loaded and inspected before your parameters have actual values. This means that fetching parameter values during global scope results in deployment failure. For cases where you want to use a parameter to initialize a global value, use the initialization callback onInit() . This callback runs before any functions run in production but is not be called during deploy time, so it is a safe place to access a parameter's value.

  const { GoogleGenerativeAI } = require('@google/generative-ai');
  const { defineSecret } = require('firebase-functions/params');
  const { onInit } = require('firebase-functions/v1');

  const apiKey = defineSecret('GOOGLE_API_KEY');

  let genAI;
  onInit(() => {
    genAI = new GoogleGenerativeAI(apiKey.value());
  })

Configure CLI behavior

Parameters can be configured with an Options object that controls how the CLI will prompt for values. The following example sets options to validate the format of a phone number, to provide a simple selection option, and to populate a selection option automatically from the Firebase project:

const { defineString } = require('firebase-functions/params');

const welcomeMessage = defineString('WELCOME_MESSAGE', {default: 'Hello World',
description: 'The greeting that is returned to the caller of this function'});

const onlyPhoneNumbers = defineString('PHONE_NUMBER', {input: {text:
{validationRegex: /\d{3}-\d{3}-\d{4}/, validationErrorMessage: "Please enter
a phone number in the format XXX-YYY-ZZZZ"}}});

const selectedOption = defineString('PARITY', {input: {select: {options:
[{value: "odd"}, {value: "even"}]}}})

const storageBucket = defineString('BUCKET', {input: {resource: {type:
"storage.googleapis.com/Bucket"}}, description: "This will automatically
populate the selector field with the deploying Cloud Project’s
storage buckets"})

انواع پارامترها

Parameterized configuration provides strong typing for parameter values, and also support secrets from Cloud Secret Manager. انواع پشتیبانی شده عبارتند از:

  • راز
  • رشته
  • بولی
  • عدد صحیح
  • شناور

Parameter values and expressions

Firebase evaluates your parameters both at deploy time and while your function is executing. Due to these dual environments, some extra care must be taken when comparing parameter values, and when using them to set runtime options for your functions.

To pass a parameter to your function as a runtime option, pass it directly:

const functions = require('firebase-functions/v1');
const { defineInt} = require('firebase-functions/params');
const minInstancesConfig = defineInt('HELLO\_WORLD\_MININSTANCES');

export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
  (req, res) => {
    //…

Additionally, if you need to compare against a parameter in order to know what option to pick, you'll need to use built-in comparators instead of checking the value:

const functions = require('firebase-functions/v1');
const { defineBool } = require('firebase-functions/params');
const environment = params.defineString(ENVIRONMENT, {default: dev});

// use built-in comparators
const minInstancesConfig =environment.equals('PRODUCTION').thenElse(10, 1);
export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
  (req, res) => {
    //…

Parameters and parameter expressions that are only used at runtime can be accessed with their value function:

const functions = require('firebase-functions/v1');
const { defineString } = require('firebase-functions/params');
const welcomeMessage = defineString('WELCOME_MESSAGE');

// To use configured parameters inside the config for a function, provide them
// directly. To use them at runtime, call .value() on them.
export const helloWorld = functions.https.onRequest(
 (req, res) => {
    res.send(`${welcomeMessage.value()}! I am a function.`);
  }
);

Built-in parameters

The Cloud Functions SDK offers three pre-defined parameters, available from the firebase-functions/params subpackage:

  • projectID — the Cloud project in which the function is running.
  • databaseURL — the URL of the Realtime Database instance associated with the function (if enabled on the Firebase project).
  • storageBucket — the Cloud Storage bucket associated with the function (if enabled on the Firebase project).

These function like user-defined string parameters in all respects, except that, since their values are always known to the Firebase CLI, their values will never be prompted for on deployment nor saved to .env files.

Secret parameters

Parameters of type Secret , defined using defineSecret() , represent string parameters which have a value stored in Cloud Secret Manager. Instead of checking against a local .env file and writing a new value to the file if missing, secret parameters check against existence in Cloud Secret Manager, and interactively prompt for the value of a new secret during deployment.

Secret parameters defined in this way must be bound to individual functions that should have access to them:

const functions = require('firebase-functions/v1');
const { defineSecret } = require('firebase-functions/params');
const discordApiKey = defineSecret('DISCORD_API_KEY');

export const postToDiscord = functions.runWith({ secrets: [discordApiKey] }).https.onRequest(
  (req, res) => {
    const apiKey = discordApiKey.value();
    //…

Because the values of secrets are hidden until execution of the function, you cannot use them while configuring your function.

متغیرهای محیطی

Cloud Functions for Firebase supports the dotenv file format for loading environment variables specified in a .env file to your application runtime. Once deployed, the environment variables can be read via the process.env interface.

To configure your environment this way, create a .env file in your project, add the desired variables, and deploy:

  1. Create a .env file in your functions/ directory:

    # Directory layout:
    #   my-project/
    #     firebase.json
    #     functions/
    #       .env
    #       package.json
    #       index.js
    
  2. Open the .env file for edit, and add the desired keys. به عنوان مثال:

    PLANET=Earth
    AUDIENCE=Humans
    
  3. Deploy functions and verify that environment variables were loaded:

    firebase deploy --only functions
    # ...
    # i functions: Loaded environment variables from .env.
    # ...
    

Once your your custom environment variables are deployed, your function code can access them with process.env syntax:

// Responds with "Hello Earth and Humans"
exports.hello = functions.https.onRequest((request, response) => {
  response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});

Deploying multiple sets of environment variables

If you need an alternative set of environment variables for your Firebase projects (such as staging vs production), create a .env. <project or alias > file and write your project-specific environment variables there. The environment variables from .env and project-specific .env files (if they exist) will be included in all deployed functions.

For example, a project could include these three files containing slightly different values for development and production:

.env .env.dev .env.prod
PLANET=Earth

AUDIENCE=Humans

AUDIENCE=Dev Humans AUDIENCE=Prod Humans

Given the values in those separate files, the set of environment variables deployed with your functions will vary depending on your target project:

$ firebase use dev
$ firebase deploy --only functions
i functions: Loaded environment variables from .env, .env.dev.
# Deploys functions with following user-defined environment variables:
#   PLANET=Earth
#   AUDIENCE=Dev Humans

$ firebase use prod
$ firebase deploy --only functions
i functions: Loaded environment variables from .env, .env.prod.
# Deploys functions with following user-defined environment variables:
#   PLANET=Earth
#   AUDIENCE=Prod Humans

متغیرهای محیطی رزرو شده

Some environment variable keys are reserved for internal use. Do not use any of these keys in your .env files:

  • All keys starting with X_GOOGLE_
  • All keys starting EXT_
  • All keys starting with FIREBASE_
  • Any key from the following list:
  • CLOUD_RUNTIME_CONFIG
  • ENTRY_POINT
  • GCP_PROJECT
  • GCLOUD_PROJECT
  • GOOGLE_CLOUD_PROJECT
  • FUNCTION_TRIGGER_TYPE
  • FUNCTION_NAME
  • FUNCTION_MEMORY_MB
  • FUNCTION_TIMEOUT_SEC
  • FUNCTION_IDENTITY
  • FUNCTION_REGION
  • FUNCTION_TARGET
  • FUNCTION_SIGNATURE_TYPE
  • K_SERVICE
  • K_REVISION
  • بندر
  • K_CONFIGURATION

Store and access sensitive configuration information

Environment variables stored in .env files can be used for function configuration, but you should not consider them a secure way to store sensitive information such as database credentials or API keys. This is especially important if you check your .env files into source control.

To help you store sensitive configuration information, Cloud Functions for Firebase integrates with Google Cloud Secret Manager . This encrypted service stores configuration values securely, while still allowing easy access from your functions when needed.

Create and use a secret

To create a secret, use the Firebase CLI.

To create and use a secret:

  1. From the root of your local project directory, run the following command:

    firebase functions:secrets:set SECRET_NAME

  2. Enter a value for SECRET_NAME .

    The CLI echoes a success message and warns that you must deploy functions for the change to take effect.

  3. Before deploying, make sure your functions code allows the function to access the secret using the runWith parameter:

    exports.processPayment = functions
      // Make the secret available to this function
      .runWith({ secrets: ["SECRET_NAME"] })
      .onCall((data, context) => {
        const myBillingService = initializeBillingService(
          // reference the secret value
          process.env.SECRET_NAME
        );
        // Process the payment
      });
  4. Deploy Cloud Functions :

    firebase deploy --only functions

Now you'll be able to access it like any other environment variable. Conversely, if another function that does not specify the secret in runWith tries to access the secret, it receives an undefined value:

  exports.anotherEndpoint = functions.https.onRequest((request, response) => {
    response.send(`The secret API key is ${process.env.SECRET_NAME}`);
    // responds with "The secret API key is undefined" because the `runWith` parameter is missing
  });

Once your function is deployed, it will have access to the secret value. Only functions that specifically include a secret in their runWith parameter will have access to that secret as an environment variable. This helps you make sure that secret values are only available where they're needed, reducing the risk of accidentally leaking a secret.

Managing secrets

Use the Firebase CLI to manage your secrets. While managing secrets this way, keep in mind that some CLI changes require you to modify and/or redeploy associated functions. به طور مشخص:

  • Whenever you set a new value for a secret, you must redeploy all functions that reference that secret for them to pick up the latest value.
  • If you delete a secret, make sure that none of your deployed functions references that secret. Functions that use a secret value that has been deleted will fail silently.

Here's a summary of the Firebase CLI commands for secret management:

# Change the value of an existing secret
firebase functions:secrets:set SECRET_NAME

# View the value of a secret
functions:secrets:access SECRET_NAME

# Destroy a secret
functions:secrets:destroy SECRET_NAME

# View all secret versions and their state
functions:secrets:get SECRET_NAME

# Automatically clean up all secrets that aren't referenced by any of your functions
functions:secrets:prune

For the access and destroy commands, you can provide the optional version parameter to manage a particular version. به عنوان مثال:

functions:secrets:access SECRET_NAME[@VERSION]

For more information about these operations, pass -h with the command to view CLI help.

How secrets are billed

Secret Manager allows 6 active secret versions at no cost. This means that you can have 6 secrets per month in a Firebase project at no cost.

By default, the Firebase CLI attempts to automatically destroy unused secret versions where appropriate, such as when you deploy functions with a new version of the secret. Also, you can actively clean up unused secrets using functions:secrets:destroy and functions:secrets:prune .

Secret Manager allows 10,000 unbilled monthly access operations on a secret. Function instances read only the secrets specified in their runWith parameter every time they cold start. If you have a lot of function instances reading a lot of secrets, your project may exceed this allowance, at which point you'll be charged $0.03 per 10,000 access operations.

For more information, see Secret Manager Pricing .

پشتیبانی شبیه ساز

Environment configuration with dotenv is designed to interoperate with a local Cloud Functions emulator .

When using a local Cloud Functions emulator, you can override environment variables for your project by setting up a .env.local file. Contents of .env.local take precedence over .env and the project-specific .env file.

For example, a project could include these three files containing slightly different values for development and local testing:

.env .env.dev .env.local
PLANET=Earth

AUDIENCE=Humans

AUDIENCE=Dev Humans AUDIENCE=Local Humans

When started in the local context, the emulator loads the environment variables as shown:

  $ firebase emulators:start
  i  emulators: Starting emulators: functions
  # Starts emulator with following environment variables:
  #  PLANET=Earth
  #  AUDIENCE=Local Humans

Secrets and credentials in the Cloud Functions emulator

The Cloud Functions emulator supports the use of secrets to store and access sensitive configuration information . By default, the emulator will try to access your production secrets using application default credentials . In certain situations like CI environments, the emulator may fail to access secret values due to permission restrictions.

Similar to Cloud Functions emulator support for environment variables, you can override secrets values by setting up a .secret.local file. This makes it easy for you to test your functions locally, especially if you don't have access to the secret value.

Migrating from environment configuration

If you have been using environment configuration with functions.config , you can migrate your existing configuration as environment variables (in dotenv format). The Firebase CLI provides an export command that outputs the configuration of each alias or project listed in your directory's .firebaserc file (in the example below, local , dev , and prod ) as .env files.

To migrate, export your existing environment configurations using the firebase functions:config:export command:

firebase functions:config:export
i  Importing configs from projects: [project-0, project-1]
⚠  The following configs keys could not be exported as environment variables:

⚠  project-0 (dev):
    1foo.a => 1FOO\_A (Key 1FOO\_A must start with an uppercase ASCII letter or underscore, and then consist of uppercase ASCII letters, digits, and underscores.)

Enter a PREFIX to rename invalid environment variable keys: CONFIG\_
✔  Wrote functions/.env.prod
✔  Wrote functions/.env.dev
✔  Wrote functions/.env.local
✔  Wrote functions/.env

Note that, in some cases, you will be prompted to enter a prefix to rename exported environment variable keys. This is because not all configurations can be automatically transformed since they may be invalid or may be a reserved environment variable key .

We recommend that you carefully review the contents of the generated .env files before you deploy your functions or check the .env files into source control. If any values are sensitive and should not be leaked, remove them from your .env files and store them securely in Secret Manager instead.

You'll also need to update your functions code. Any functions that use functions.config will now need to use process.env instead, as shown in Upgrade to 2nd gen .

پیکربندی محیط

Set environment configuration with the CLI

To store environment data, you can use the firebase functions:config:set command in the Firebase CLI . Each key can be namespaced using periods to group related configuration together. Keep in mind that only lowercase characters are accepted in keys ; uppercase characters are not allowed.

For instance, to store the Client ID and API key for "Some Service", you might run:

firebase functions:config:set someservice.key="THE API KEY" someservice.id="THE CLIENT ID"

Retrieve current environment configuration

To inspect what's currently stored in environment config for your project, you can use firebase functions:config:get . It will output JSON something like this:

{
  "someservice": {
    "key":"THE API KEY",
    "id":"THE CLIENT ID"
  }
}

This functionality is based on the Google Cloud Runtime Configuration API .

Use functions.config to access environment configuration in a function

Some configuration is automatically provided under the reserved firebase namespace. Environment configuration is made available inside your running function via functions.config() . To use the configuration above, your code might look like this:

const functions = require('firebase-functions/v1');
const request = require('request-promise');

exports.userCreated = functions.database.ref('/users/{id}').onWrite(event => {
  let email = event.data.child('email').val();

  return request({
    url: 'https://someservice.com/api/some/call',
    headers: {
      'X-Client-ID': functions.config().someservice.id,
      'Authorization': `Bearer ${functions.config().someservice.key}`
    },
    body: {email: email}
  });
});

Use environment configuration to initialize a module

Some Node modules are ready without any configuration. Other modules need extra configuration to initialize correctly. We recommend you store this configuration in environment configuration variables rather than hard-coding it. This helps you keep your code much more portable, which lets you open source your application or easily switch between production and staging versions.

For example, to use the Slack Node SDK module, you might write this:

const functions = require('firebase-functions/v1');
const IncomingWebhook = require('@slack/client').IncomingWebhook;
const webhook = new IncomingWebhook(functions.config().slack.url);

Prior to deploying, set the slack.url environment config variable:

firebase functions:config:set slack.url=https://hooks.slack.com/services/XXX

Additional Environment Commands

  • firebase functions:config:unset key1 key2 removes the specified keys from the config
  • firebase functions:config:clone --from <fromProject> clones another project's environment into the currently active project.

Automatically populated environment variables

There are environment variables that are automatically populated in the functions runtime and in locally emulated functions. These include those populated by Google Cloud , as well as a Firebase-specific environment variable:

process.env.FIREBASE_CONFIG : Provides the following Firebase project config info:

{
  databaseURL: 'https://DATABASE_NAME.firebaseio.com',
  storageBucket: 'PROJECT_ID.firebasestorage.app',
  projectId: 'PROJECT_ID'
}

Note that the values in your actual Firebase configuration might vary depending on the resources you've provisioned in your project.

This configuration is applied automatically when you initialize the Firebase Admin SDK with no arguments. If you are writing functions in JavaScript, initialize like this:

const admin = require('firebase-admin');
admin.initializeApp();

If you are writing functions in TypeScript, initialize like this:

import * as functions from 'firebase-functions/v1';
import * as admin from 'firebase-admin';
import 'firebase-functions/v1';
admin.initializeApp();

If you need to initialize the Admin SDK with the default project configuration using service account credentials, you can load the credentials from a file and add them to FIREBASE_CONFIG like this:

serviceAccount = require('./serviceAccount.json');

const adminConfig = JSON.parse(process.env.FIREBASE_CONFIG);
adminConfig.credential = admin.credential.cert(serviceAccount);
admin.initializeApp(adminConfig);
،


Often you'll need additional configuration for your functions, such as third-party API keys or tuneable settings. The Firebase SDK for Cloud Functions offers built-in environment configuration to make it easy to store and retrieve this type of data for your project.

You can choose between these options:

  • Parameterized configuration (recommended for most scenarios). This provides strongly-typed environment configuration with parameters that are validated at deploy time, which prevents errors and simplifies debugging.
  • File-based configuration of environment variables . With this approach, you manually create a dotenv file for loading environment variables.

For most use cases, parameterized configuration is recommended. This approach makes configuration values available both at runtime and deploy time, and deployment is blocked unless all parameters have a valid value. Conversely, configuration with environment variables is not available at deploy time.

Parameterized configuration

Cloud Functions for Firebase provides an interface for defining configuration parameters declaratively inside your codebase. The value of these parameters is available both during function deployment, when setting deployment and runtime options, and during execution. This means that the CLI will block deployment unless all parameters have a valid value.

To define parameters in your code, follow this model:

const functions = require('firebase-functions/v1');
const { defineInt, defineString } = require('firebase-functions/params');

// Define some parameters
const minInstancesConfig = defineInt('HELLO_WORLD_MININSTANCES');
const welcomeMessage = defineString('WELCOME_MESSAGE');

// To use configured parameters inside the config for a function, provide them
// directly. To use them at runtime, call .value() on them.
export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
  (req, res) => {
    res.send(`${welcomeMessage.value()}! I am a function.`);
  }
);

When deploying a function with parameterized configuration variables, the Firebase CLI first attempts to load their values from local .env files. If they are not present in those files and no default is set, the CLI will prompt for the values during deployment, and then automatically save their values to a .env file named .env.<project_ID> in your functions/ directory:

$ firebase deploy
i  functions: preparing codebase default for deployment
? Enter a string value for ENVIRONMENT: prod
i  functions: Writing new parameter values to disk: .env.projectId
…
$ firebase deploy
i  functions: Loaded environment variables from .env.projectId

Depending on your development workflow, it may be useful to add the generated .env.<project_ID> file to version control.

Using parameters in global scope

During deployment, your functions code is loaded and inspected before your parameters have actual values. This means that fetching parameter values during global scope results in deployment failure. For cases where you want to use a parameter to initialize a global value, use the initialization callback onInit() . This callback runs before any functions run in production but is not be called during deploy time, so it is a safe place to access a parameter's value.

  const { GoogleGenerativeAI } = require('@google/generative-ai');
  const { defineSecret } = require('firebase-functions/params');
  const { onInit } = require('firebase-functions/v1');

  const apiKey = defineSecret('GOOGLE_API_KEY');

  let genAI;
  onInit(() => {
    genAI = new GoogleGenerativeAI(apiKey.value());
  })

Configure CLI behavior

Parameters can be configured with an Options object that controls how the CLI will prompt for values. The following example sets options to validate the format of a phone number, to provide a simple selection option, and to populate a selection option automatically from the Firebase project:

const { defineString } = require('firebase-functions/params');

const welcomeMessage = defineString('WELCOME_MESSAGE', {default: 'Hello World',
description: 'The greeting that is returned to the caller of this function'});

const onlyPhoneNumbers = defineString('PHONE_NUMBER', {input: {text:
{validationRegex: /\d{3}-\d{3}-\d{4}/, validationErrorMessage: "Please enter
a phone number in the format XXX-YYY-ZZZZ"}}});

const selectedOption = defineString('PARITY', {input: {select: {options:
[{value: "odd"}, {value: "even"}]}}})

const storageBucket = defineString('BUCKET', {input: {resource: {type:
"storage.googleapis.com/Bucket"}}, description: "This will automatically
populate the selector field with the deploying Cloud Project’s
storage buckets"})

انواع پارامترها

Parameterized configuration provides strong typing for parameter values, and also support secrets from Cloud Secret Manager. انواع پشتیبانی شده عبارتند از:

  • راز
  • رشته
  • بولی
  • عدد صحیح
  • شناور

Parameter values and expressions

Firebase evaluates your parameters both at deploy time and while your function is executing. Due to these dual environments, some extra care must be taken when comparing parameter values, and when using them to set runtime options for your functions.

To pass a parameter to your function as a runtime option, pass it directly:

const functions = require('firebase-functions/v1');
const { defineInt} = require('firebase-functions/params');
const minInstancesConfig = defineInt('HELLO\_WORLD\_MININSTANCES');

export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
  (req, res) => {
    //…

Additionally, if you need to compare against a parameter in order to know what option to pick, you'll need to use built-in comparators instead of checking the value:

const functions = require('firebase-functions/v1');
const { defineBool } = require('firebase-functions/params');
const environment = params.defineString(ENVIRONMENT, {default: dev});

// use built-in comparators
const minInstancesConfig =environment.equals('PRODUCTION').thenElse(10, 1);
export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
  (req, res) => {
    //…

Parameters and parameter expressions that are only used at runtime can be accessed with their value function:

const functions = require('firebase-functions/v1');
const { defineString } = require('firebase-functions/params');
const welcomeMessage = defineString('WELCOME_MESSAGE');

// To use configured parameters inside the config for a function, provide them
// directly. To use them at runtime, call .value() on them.
export const helloWorld = functions.https.onRequest(
 (req, res) => {
    res.send(`${welcomeMessage.value()}! I am a function.`);
  }
);

Built-in parameters

The Cloud Functions SDK offers three pre-defined parameters, available from the firebase-functions/params subpackage:

  • projectID — the Cloud project in which the function is running.
  • databaseURL — the URL of the Realtime Database instance associated with the function (if enabled on the Firebase project).
  • storageBucket — the Cloud Storage bucket associated with the function (if enabled on the Firebase project).

These function like user-defined string parameters in all respects, except that, since their values are always known to the Firebase CLI, their values will never be prompted for on deployment nor saved to .env files.

Secret parameters

Parameters of type Secret , defined using defineSecret() , represent string parameters which have a value stored in Cloud Secret Manager. Instead of checking against a local .env file and writing a new value to the file if missing, secret parameters check against existence in Cloud Secret Manager, and interactively prompt for the value of a new secret during deployment.

Secret parameters defined in this way must be bound to individual functions that should have access to them:

const functions = require('firebase-functions/v1');
const { defineSecret } = require('firebase-functions/params');
const discordApiKey = defineSecret('DISCORD_API_KEY');

export const postToDiscord = functions.runWith({ secrets: [discordApiKey] }).https.onRequest(
  (req, res) => {
    const apiKey = discordApiKey.value();
    //…

Because the values of secrets are hidden until execution of the function, you cannot use them while configuring your function.

متغیرهای محیطی

Cloud Functions for Firebase supports the dotenv file format for loading environment variables specified in a .env file to your application runtime. Once deployed, the environment variables can be read via the process.env interface.

To configure your environment this way, create a .env file in your project, add the desired variables, and deploy:

  1. Create a .env file in your functions/ directory:

    # Directory layout:
    #   my-project/
    #     firebase.json
    #     functions/
    #       .env
    #       package.json
    #       index.js
    
  2. Open the .env file for edit, and add the desired keys. به عنوان مثال:

    PLANET=Earth
    AUDIENCE=Humans
    
  3. Deploy functions and verify that environment variables were loaded:

    firebase deploy --only functions
    # ...
    # i functions: Loaded environment variables from .env.
    # ...
    

Once your your custom environment variables are deployed, your function code can access them with process.env syntax:

// Responds with "Hello Earth and Humans"
exports.hello = functions.https.onRequest((request, response) => {
  response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});

Deploying multiple sets of environment variables

If you need an alternative set of environment variables for your Firebase projects (such as staging vs production), create a .env. <project or alias > file and write your project-specific environment variables there. The environment variables from .env and project-specific .env files (if they exist) will be included in all deployed functions.

For example, a project could include these three files containing slightly different values for development and production:

.env .env.dev .env.prod
PLANET=Earth

AUDIENCE=Humans

AUDIENCE=Dev Humans AUDIENCE=Prod Humans

Given the values in those separate files, the set of environment variables deployed with your functions will vary depending on your target project:

$ firebase use dev
$ firebase deploy --only functions
i functions: Loaded environment variables from .env, .env.dev.
# Deploys functions with following user-defined environment variables:
#   PLANET=Earth
#   AUDIENCE=Dev Humans

$ firebase use prod
$ firebase deploy --only functions
i functions: Loaded environment variables from .env, .env.prod.
# Deploys functions with following user-defined environment variables:
#   PLANET=Earth
#   AUDIENCE=Prod Humans

متغیرهای محیطی رزرو شده

Some environment variable keys are reserved for internal use. Do not use any of these keys in your .env files:

  • All keys starting with X_GOOGLE_
  • All keys starting EXT_
  • All keys starting with FIREBASE_
  • Any key from the following list:
  • CLOUD_RUNTIME_CONFIG
  • ENTRY_POINT
  • GCP_PROJECT
  • GCLOUD_PROJECT
  • GOOGLE_CLOUD_PROJECT
  • FUNCTION_TRIGGER_TYPE
  • FUNCTION_NAME
  • FUNCTION_MEMORY_MB
  • FUNCTION_TIMEOUT_SEC
  • FUNCTION_IDENTITY
  • FUNCTION_REGION
  • FUNCTION_TARGET
  • FUNCTION_SIGNATURE_TYPE
  • K_SERVICE
  • K_REVISION
  • بندر
  • K_CONFIGURATION

Store and access sensitive configuration information

Environment variables stored in .env files can be used for function configuration, but you should not consider them a secure way to store sensitive information such as database credentials or API keys. This is especially important if you check your .env files into source control.

To help you store sensitive configuration information, Cloud Functions for Firebase integrates with Google Cloud Secret Manager . This encrypted service stores configuration values securely, while still allowing easy access from your functions when needed.

Create and use a secret

To create a secret, use the Firebase CLI.

To create and use a secret:

  1. From the root of your local project directory, run the following command:

    firebase functions:secrets:set SECRET_NAME

  2. Enter a value for SECRET_NAME .

    The CLI echoes a success message and warns that you must deploy functions for the change to take effect.

  3. Before deploying, make sure your functions code allows the function to access the secret using the runWith parameter:

    exports.processPayment = functions
      // Make the secret available to this function
      .runWith({ secrets: ["SECRET_NAME"] })
      .onCall((data, context) => {
        const myBillingService = initializeBillingService(
          // reference the secret value
          process.env.SECRET_NAME
        );
        // Process the payment
      });
  4. Deploy Cloud Functions :

    firebase deploy --only functions

Now you'll be able to access it like any other environment variable. Conversely, if another function that does not specify the secret in runWith tries to access the secret, it receives an undefined value:

  exports.anotherEndpoint = functions.https.onRequest((request, response) => {
    response.send(`The secret API key is ${process.env.SECRET_NAME}`);
    // responds with "The secret API key is undefined" because the `runWith` parameter is missing
  });

Once your function is deployed, it will have access to the secret value. Only functions that specifically include a secret in their runWith parameter will have access to that secret as an environment variable. This helps you make sure that secret values are only available where they're needed, reducing the risk of accidentally leaking a secret.

Managing secrets

Use the Firebase CLI to manage your secrets. While managing secrets this way, keep in mind that some CLI changes require you to modify and/or redeploy associated functions. به طور مشخص:

  • Whenever you set a new value for a secret, you must redeploy all functions that reference that secret for them to pick up the latest value.
  • If you delete a secret, make sure that none of your deployed functions references that secret. Functions that use a secret value that has been deleted will fail silently.

Here's a summary of the Firebase CLI commands for secret management:

# Change the value of an existing secret
firebase functions:secrets:set SECRET_NAME

# View the value of a secret
functions:secrets:access SECRET_NAME

# Destroy a secret
functions:secrets:destroy SECRET_NAME

# View all secret versions and their state
functions:secrets:get SECRET_NAME

# Automatically clean up all secrets that aren't referenced by any of your functions
functions:secrets:prune

For the access and destroy commands, you can provide the optional version parameter to manage a particular version. به عنوان مثال:

functions:secrets:access SECRET_NAME[@VERSION]

For more information about these operations, pass -h with the command to view CLI help.

How secrets are billed

Secret Manager allows 6 active secret versions at no cost. This means that you can have 6 secrets per month in a Firebase project at no cost.

By default, the Firebase CLI attempts to automatically destroy unused secret versions where appropriate, such as when you deploy functions with a new version of the secret. Also, you can actively clean up unused secrets using functions:secrets:destroy and functions:secrets:prune .

Secret Manager allows 10,000 unbilled monthly access operations on a secret. Function instances read only the secrets specified in their runWith parameter every time they cold start. If you have a lot of function instances reading a lot of secrets, your project may exceed this allowance, at which point you'll be charged $0.03 per 10,000 access operations.

For more information, see Secret Manager Pricing .

پشتیبانی شبیه ساز

Environment configuration with dotenv is designed to interoperate with a local Cloud Functions emulator .

When using a local Cloud Functions emulator, you can override environment variables for your project by setting up a .env.local file. Contents of .env.local take precedence over .env and the project-specific .env file.

For example, a project could include these three files containing slightly different values for development and local testing:

.env .env.dev .env.local
PLANET=Earth

AUDIENCE=Humans

AUDIENCE=Dev Humans AUDIENCE=Local Humans

When started in the local context, the emulator loads the environment variables as shown:

  $ firebase emulators:start
  i  emulators: Starting emulators: functions
  # Starts emulator with following environment variables:
  #  PLANET=Earth
  #  AUDIENCE=Local Humans

Secrets and credentials in the Cloud Functions emulator

The Cloud Functions emulator supports the use of secrets to store and access sensitive configuration information . By default, the emulator will try to access your production secrets using application default credentials . In certain situations like CI environments, the emulator may fail to access secret values due to permission restrictions.

Similar to Cloud Functions emulator support for environment variables, you can override secrets values by setting up a .secret.local file. This makes it easy for you to test your functions locally, especially if you don't have access to the secret value.

Migrating from environment configuration

If you have been using environment configuration with functions.config , you can migrate your existing configuration as environment variables (in dotenv format). The Firebase CLI provides an export command that outputs the configuration of each alias or project listed in your directory's .firebaserc file (in the example below, local , dev , and prod ) as .env files.

To migrate, export your existing environment configurations using the firebase functions:config:export command:

firebase functions:config:export
i  Importing configs from projects: [project-0, project-1]
⚠  The following configs keys could not be exported as environment variables:

⚠  project-0 (dev):
    1foo.a => 1FOO\_A (Key 1FOO\_A must start with an uppercase ASCII letter or underscore, and then consist of uppercase ASCII letters, digits, and underscores.)

Enter a PREFIX to rename invalid environment variable keys: CONFIG\_
✔  Wrote functions/.env.prod
✔  Wrote functions/.env.dev
✔  Wrote functions/.env.local
✔  Wrote functions/.env

Note that, in some cases, you will be prompted to enter a prefix to rename exported environment variable keys. This is because not all configurations can be automatically transformed since they may be invalid or may be a reserved environment variable key .

We recommend that you carefully review the contents of the generated .env files before you deploy your functions or check the .env files into source control. If any values are sensitive and should not be leaked, remove them from your .env files and store them securely in Secret Manager instead.

You'll also need to update your functions code. Any functions that use functions.config will now need to use process.env instead, as shown in Upgrade to 2nd gen .

پیکربندی محیط

Set environment configuration with the CLI

To store environment data, you can use the firebase functions:config:set command in the Firebase CLI . Each key can be namespaced using periods to group related configuration together. Keep in mind that only lowercase characters are accepted in keys ; uppercase characters are not allowed.

For instance, to store the Client ID and API key for "Some Service", you might run:

firebase functions:config:set someservice.key="THE API KEY" someservice.id="THE CLIENT ID"

Retrieve current environment configuration

To inspect what's currently stored in environment config for your project, you can use firebase functions:config:get . It will output JSON something like this:

{
  "someservice": {
    "key":"THE API KEY",
    "id":"THE CLIENT ID"
  }
}

This functionality is based on the Google Cloud Runtime Configuration API .

Use functions.config to access environment configuration in a function

Some configuration is automatically provided under the reserved firebase namespace. Environment configuration is made available inside your running function via functions.config() . To use the configuration above, your code might look like this:

const functions = require('firebase-functions/v1');
const request = require('request-promise');

exports.userCreated = functions.database.ref('/users/{id}').onWrite(event => {
  let email = event.data.child('email').val();

  return request({
    url: 'https://someservice.com/api/some/call',
    headers: {
      'X-Client-ID': functions.config().someservice.id,
      'Authorization': `Bearer ${functions.config().someservice.key}`
    },
    body: {email: email}
  });
});

Use environment configuration to initialize a module

Some Node modules are ready without any configuration. Other modules need extra configuration to initialize correctly. We recommend you store this configuration in environment configuration variables rather than hard-coding it. This helps you keep your code much more portable, which lets you open source your application or easily switch between production and staging versions.

For example, to use the Slack Node SDK module, you might write this:

const functions = require('firebase-functions/v1');
const IncomingWebhook = require('@slack/client').IncomingWebhook;
const webhook = new IncomingWebhook(functions.config().slack.url);

Prior to deploying, set the slack.url environment config variable:

firebase functions:config:set slack.url=https://hooks.slack.com/services/XXX

Additional Environment Commands

  • firebase functions:config:unset key1 key2 removes the specified keys from the config
  • firebase functions:config:clone --from <fromProject> clones another project's environment into the currently active project.

Automatically populated environment variables

There are environment variables that are automatically populated in the functions runtime and in locally emulated functions. These include those populated by Google Cloud , as well as a Firebase-specific environment variable:

process.env.FIREBASE_CONFIG : Provides the following Firebase project config info:

{
  databaseURL: 'https://DATABASE_NAME.firebaseio.com',
  storageBucket: 'PROJECT_ID.firebasestorage.app',
  projectId: 'PROJECT_ID'
}

Note that the values in your actual Firebase configuration might vary depending on the resources you've provisioned in your project.

This configuration is applied automatically when you initialize the Firebase Admin SDK with no arguments. If you are writing functions in JavaScript, initialize like this:

const admin = require('firebase-admin');
admin.initializeApp();

If you are writing functions in TypeScript, initialize like this:

import * as functions from 'firebase-functions/v1';
import * as admin from 'firebase-admin';
import 'firebase-functions/v1';
admin.initializeApp();

If you need to initialize the Admin SDK with the default project configuration using service account credentials, you can load the credentials from a file and add them to FIREBASE_CONFIG like this:

serviceAccount = require('./serviceAccount.json');

const adminConfig = JSON.parse(process.env.FIREBASE_CONFIG);
adminConfig.credential = admin.credential.cert(serviceAccount);
admin.initializeApp(adminConfig);