اغلب برای عملکردهای خود به پیکربندی اضافی نیاز دارید، مانند کلیدهای 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
در پروژه خود ایجاد کنید، متغیرهای مورد نظر را اضافه کنید و اجرا کنید:
یک فایل
.env
درfunctions/
دایرکتوری خود ایجاد کنید:# Directory layout: # my-project/ # firebase.json # functions/ # .env # package.json # index.js
فایل
.env
را برای ویرایش باز کرده و کلیدهای مورد نظر را اضافه کنید. به عنوان مثال:PLANET=Earth AUDIENCE=Humans
توابع را مستقر کنید و بررسی کنید که متغیرهای محیط بارگذاری شده اند:
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 استفاده کنید.
برای ایجاد و استفاده از یک راز:
از ریشه دایرکتوری پروژه محلی خود، دستور زیر را اجرا کنید:
firebase functions:secrets:set
SECRET_NAME یک مقدار برای SECRET_NAME وارد کنید.
CLI یک پیام موفقیت آمیز را بازتاب می دهد و هشدار می دهد که باید توابع را برای اعمال تغییر مستقر کنید.
قبل از استقرار، مطمئن شوید که کد توابع شما به تابع اجازه می دهد تا با استفاده از پارامتر
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 });
استقرار 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:setSECRET_NAME # View the value of a secret functions:secrets:accessSECRET_NAME # Destroy a secret functions:secrets:destroySECRET_NAME # View all secret versions and their state functions:secrets:getSECRET_NAME # Automatically clean up all secrets that aren't referenced by any of your functions functions:secrets:prune
برای دستورات access
و destroy
، می توانید پارامتر نسخه اختیاری را برای مدیریت یک نسخه خاص ارائه دهید. به عنوان مثال:
functions:secrets:accessSECRET_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
را در پروژه خود ایجاد کنید ، متغیرهای مورد نظر را اضافه کرده و مستقر کنید:
یک فایل
.env
را درfunctions/
فهرست خود ایجاد کنید:# Directory layout: # my-project/ # firebase.json # functions/ # .env # package.json # index.js
پرونده
.env
را برای ویرایش باز کنید و کلیدهای مورد نظر را اضافه کنید. به عنوان مثال:PLANET=Earth AUDIENCE=Humans
توابع را مستقر کنید و تأیید کنید که متغیرهای محیط بارگیری شده اند:
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 استفاده کنید.
برای ایجاد و استفاده از یک راز:
از ریشه دایرکتوری پروژه محلی خود ، دستور زیر را اجرا کنید:
firebase functions:secrets:set
SECRET_NAME یک مقدار برای SECRET_NAME وارد کنید.
CLI یک پیام موفقیت آمیز را تکرار می کند و هشدار می دهد که شما باید توابع خود را برای تغییر اعمال کنید.
قبل از استقرار ، اطمینان حاصل کنید که کد توابع شما با استفاده از پارامتر
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 });
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:setSECRET_NAME # View the value of a secret functions:secrets:accessSECRET_NAME # Destroy a secret functions:secrets:destroySECRET_NAME # View all secret versions and their state functions:secrets:getSECRET_NAME # Automatically clean up all secrets that aren't referenced by any of your functions functions:secrets:prune
برای دستورات access
و destroy
، می توانید پارامتر نسخه اختیاری را برای مدیریت یک نسخه خاص ارائه دهید. به عنوان مثال:
functions:secrets:accessSECRET_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:
Create a
.env
file in yourfunctions/
directory:# Directory layout: # my-project/ # firebase.json # functions/ # .env # package.json # index.js
Open the
.env
file for edit, and add the desired keys. به عنوان مثال:PLANET=Earth AUDIENCE=Humans
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:
From the root of your local project directory, run the following command:
firebase functions:secrets:set
SECRET_NAME 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.
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 });
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:setSECRET_NAME # View the value of a secret functions:secrets:accessSECRET_NAME # Destroy a secret functions:secrets:destroySECRET_NAME # View all secret versions and their state functions:secrets:getSECRET_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:accessSECRET_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:
Create a
.env
file in yourfunctions/
directory:# Directory layout: # my-project/ # firebase.json # functions/ # .env # package.json # index.js
Open the
.env
file for edit, and add the desired keys. به عنوان مثال:PLANET=Earth AUDIENCE=Humans
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:
From the root of your local project directory, run the following command:
firebase functions:secrets:set
SECRET_NAME 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.
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 });
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:setSECRET_NAME # View the value of a secret functions:secrets:accessSECRET_NAME # Destroy a secret functions:secrets:destroySECRET_NAME # View all secret versions and their state functions:secrets:getSECRET_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:accessSECRET_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);