לעתים קרובות תזדקק לתצורה נוספת עבור הפונקציות שלך, כגון מפתחות API של צד שלישי או הגדרות ניתנות לכיוונון. Firebase SDK for Cloud Functions מציע תצורת סביבה מובנית כדי להקל על אחסון ושליפה של סוג זה של נתונים עבור הפרויקט שלך.
אתה יכול לבחור בין שלוש אפשרויות:
- תצורה עם פרמטרים (מומלץ עבור רוב התרחישים). זה מספק תצורת סביבה מוקפדת היטב עם פרמטרים המאומתים בזמן הפריסה, מה שמונע שגיאות ומפשט את ניפוי הבאגים.
- תצורה מבוססת קבצים של משתני סביבה . עם גישה זו, אתה יוצר באופן ידני קובץ dotenv לטעינת משתני סביבה.
- תצורת סביבת זמן ריצה עם Firebase CLI ו-
functions.config
.
עבור רוב מקרי השימוש, מומלצת תצורה עם פרמטרים. גישה זו הופכת ערכי תצורה לזמינים הן בזמן הריצה והן בזמן הפריסה, והפריסה חסומה אלא אם לכל הפרמטרים יש ערך חוקי. לעומת זאת, תצורה עם משתני סביבה אינה זמינה בזמן הפריסה.
תצורה עם פרמטרים
Cloud Functions for Firebase מספק ממשק להגדרת פרמטרי תצורה באופן הצהרתי בתוך בסיס הקוד שלך. הערך של פרמטרים אלה זמין הן במהלך פריסת הפונקציות, בעת הגדרת אפשרויות פריסה וזמן ריצה, והן במהלך ביצוע. המשמעות היא שה-CLI יחסום את הפריסה אלא אם לכל הפרמטרים יש ערך חוקי.
כדי להגדיר פרמטרים בקוד שלך, עקוב אחר המודל הזה:
const functions = require('firebase-functions');
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.`);
}
);
בעת פריסת פונקציה עם משתני תצורה עם פרמטרים, ה-CLI של Firebase מנסה תחילה לטעון את הערכים שלהם מקובצי .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>
שנוצר לבקרת הגירסה.
הגדר התנהגות 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');
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');
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');
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
- כתובת האתר של מופע Realtime Database המשויך לפונקציה (אם מופעלת בפרויקט Firebase). -
storageBucket
- דלי ה-Cloud Storage המשויך לפונקציה (אם מופעל בפרויקט Firebase).
אלה מתפקדים כמו פרמטרי מחרוזת המוגדרים על ידי המשתמש מכל הבחינות, פרט לכך, מכיוון שהערכים שלהם ידועים תמיד ל-Firebase CLI, לעולם לא יתבקשו לבצע את הערכים שלהם בזמן הפריסה ולא יישמרו בקבצי .env
.
פרמטרים סודיים
פרמטרים מסוג Secret
, המוגדרים באמצעות defineSecret()
, מייצגים פרמטרים של מחרוזת שיש להם ערך המאוחסן ב-Cloud Secret Manager. במקום לבדוק מול קובץ .env
מקומי ולכתוב ערך חדש לקובץ אם חסר, פרמטרים סודיים בודקים את קיומם ב-Cloud Secret Manager, ומבקשים באופן אינטראקטיבי את הערך של סוד חדש במהלך הפריסה.
פרמטרים סודיים המוגדרים בדרך זו חייבים להיות קשורים לפונקציות בודדות שאמורות להיות להם גישה אליהם:
const functions = require('firebase-functions');
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
:
// 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=Dev Humans | קהל = אנשים יצרניים |
בהתחשב בערכים באותם קבצים נפרדים, קבוצת משתני הסביבה הנפרסת עם הפונקציות שלך תשתנה בהתאם לפרויקט היעד שלך:
$ 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
- 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 });
פריסת פונקציות ענן:
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
שלהן תהיה גישה לסוד זה כמשתנה סביבה. זה עוזר לך לוודא שערכים סודיים זמינים רק היכן שהם נחוצים, ומפחית את הסיכון של דליפת סוד בטעות.
ניהול סודות
השתמש ב-CLI של Firebase כדי לנהל את הסודות שלך. בזמן ניהול סודות בדרך זו, זכור שחלק משינויי 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 ללא עלות.
כברירת מחדל, ה-CLI של Firebase מנסה להשמיד אוטומטית גרסאות סודיות שאינן בשימוש במידת הצורך, כגון כאשר אתה פורס פונקציות עם גרסה חדשה של הסוד. כמו כן, אתה יכול לנקות באופן פעיל סודות שאינם בשימוש באמצעות functions:secrets:destroy
ו- functions:secrets:prune
.
Secret Manager מאפשר 10,000 פעולות גישה חודשיות ללא חיוב בסוד. מופעי פונקציות קוראים רק את הסודות שצוינו בפרמטר runWith
שלהם בכל פעם שהם מתחילים בקרה. אם יש לך הרבה מופעי פונקציות שקוראים הרבה סודות, הפרויקט שלך עלול לחרוג מהקצבה הזו, ובשלב זה תחויב ב-$0.03 לכל 10,000 פעולות גישה.
למידע נוסף, ראה תמחור מנהל סודי .
תמיכה באמולטור
תצורת הסביבה עם dotenv נועדה לפעול יחד עם אמולטור ענן פונקציות מקומי.
בעת שימוש באמולטור Cloud Functions מקומי, אתה יכול לעקוף משתני סביבה עבור הפרויקט שלך על ידי הגדרת קובץ .env.local
. התוכן של .env.local
עדיפות על .env
וקובץ ה- .env
הספציפי לפרויקט.
לדוגמה, פרויקט יכול לכלול את שלושת הקבצים האלה המכילים ערכים מעט שונים לפיתוח ובדיקות מקומיות:
.env | .env.dev | .env.local |
PLANET=כדור הארץ קהל=בני אדם | AUDIENCE=Dev Humans | קהל = בני אדם מקומיים |
כאשר מופעל בהקשר המקומי, האמולטור טוען את משתני הסביבה כפי שמוצג:
$ 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 ). ה-CLI של Firebase מספק פקודת ייצוא שמוציאה את התצורה של כל כינוי או פרויקט המופיעים בקובץ .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
במקום זאת, כפי שמוצג במשתני הסביבה .
תצורת סביבה
לפני שפורסמה תמיכת משתני סביבה ב- firebase-functions v3.18.0
, שימוש functions.config()
היה הגישה המומלצת לתצורת סביבה. גישה זו עדיין נתמכת, אך אנו ממליצים לכל הפרויקטים החדשים להשתמש במשתני סביבה במקום זאת, מכיוון שהם פשוטים יותר לשימוש ומשפרים את הניידות של הקוד שלך.
הגדר תצורת סביבה עם ה-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"
}
}
פונקציונליות זו מבוססת על Google Cloud Runtime Configuration API .
השתמש functions.config
כדי לגשת לתצורת הסביבה בפונקציה
תצורה מסויימת מסופקת אוטומטית תחת מרחב השמות השמור firebase
. תצורת הסביבה זמינה בתוך פונקציית ההפעלה שלך באמצעות functions.config()
. כדי להשתמש בתצורה שלמעלה, הקוד שלך עשוי להיראות כך:
const functions = require('firebase-functions');
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 מוכנים ללא כל תצורה. מודולים אחרים זקוקים לתצורה נוספת כדי לאתחל כהלכה. אנו ממליצים לאחסן את התצורה הזו במשתני תצורת הסביבה במקום לקודד אותה. זה עוזר לך לשמור על הקוד שלך הרבה יותר נייד, מה שמאפשר לך לפתוח את היישום שלך בקוד קוד או לעבור בקלות בין גרסאות ייצור ל-Staging.
לדוגמה, כדי להשתמש במודול Slack Node SDK , תוכל לכתוב את זה:
const functions = require('firebase-functions');
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://databaseName.firebaseio.com',
storageBucket: 'projectId.appspot.com',
projectId: 'projectId'
}
תצורה זו מוחלת באופן אוטומטי כאשר אתה מאתחל את Firebase Admin SDK ללא ארגומנטים. אם אתה כותב פונקציות ב-JavaScript, אתחול כך:
const admin = require('firebase-admin');
admin.initializeApp();
אם אתה כותב פונקציות ב-TypeScript, אתחול כך:
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import 'firebase-functions';
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 לטעינת משתני סביבה.
- תצורת סביבת זמן ריצה עם Firebase CLI ו-
functions.config
.
עבור רוב מקרי השימוש, מומלצת תצורה עם פרמטרים. גישה זו הופכת ערכי תצורה לזמינים הן בזמן הריצה והן בזמן הפריסה, והפריסה חסומה אלא אם לכל הפרמטרים יש ערך חוקי. לעומת זאת, תצורה עם משתני סביבה אינה זמינה בזמן הפריסה.
תצורה עם פרמטרים
Cloud Functions for Firebase מספק ממשק להגדרת פרמטרי תצורה באופן הצהרתי בתוך בסיס הקוד שלך. הערך של פרמטרים אלה זמין הן במהלך פריסת הפונקציות, בעת הגדרת אפשרויות פריסה וזמן ריצה, והן במהלך ביצוע. המשמעות היא שה-CLI יחסום את הפריסה אלא אם לכל הפרמטרים יש ערך חוקי.
כדי להגדיר פרמטרים בקוד שלך, עקוב אחר המודל הזה:
const functions = require('firebase-functions');
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.`);
}
);
בעת פריסת פונקציה עם משתני תצורה עם פרמטרים, ה-CLI של Firebase מנסה תחילה לטעון את הערכים שלהם מקובצי .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>
שנוצר לבקרת הגירסה.
הגדר התנהגות 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');
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');
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');
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
- כתובת האתר של מופע Realtime Database המשויך לפונקציה (אם מופעלת בפרויקט Firebase). -
storageBucket
- דלי ה-Cloud Storage המשויך לפונקציה (אם מופעל בפרויקט Firebase).
אלה מתפקדים כמו פרמטרי מחרוזת המוגדרים על ידי המשתמש מכל הבחינות, פרט לכך, מכיוון שהערכים שלהם ידועים תמיד ל-Firebase CLI, לעולם לא יתבקשו לבצע את הערכים שלהם בזמן הפריסה ולא יישמרו בקבצי .env
.
פרמטרים סודיים
פרמטרים מסוג Secret
, המוגדרים באמצעות defineSecret()
, מייצגים פרמטרים של מחרוזת שיש להם ערך המאוחסן ב-Cloud Secret Manager. במקום לבדוק מול קובץ .env
מקומי ולכתוב ערך חדש לקובץ אם חסר, פרמטרים סודיים בודקים את קיומם ב-Cloud Secret Manager, ומבקשים באופן אינטראקטיבי את הערך של סוד חדש במהלך הפריסה.
פרמטרים סודיים המוגדרים בדרך זו חייבים להיות קשורים לפונקציות בודדות שאמורות להיות להם גישה אליהם:
const functions = require('firebase-functions');
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
:
// 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=Dev Humans | קהל = אנשים יצרניים |
בהתחשב בערכים באותם קבצים נפרדים, קבוצת משתני הסביבה הנפרסת עם הפונקציות שלך תשתנה בהתאם לפרויקט היעד שלך:
$ 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
- 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 });
פריסת פונקציות ענן:
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
שלהן תהיה גישה לסוד זה כמשתנה סביבה. זה עוזר לך לוודא שערכים סודיים זמינים רק היכן שהם נחוצים, ומפחית את הסיכון של דליפת סוד בטעות.
ניהול סודות
השתמש ב-CLI של Firebase כדי לנהל את הסודות שלך. בזמן ניהול סודות בדרך זו, זכור שחלק משינויי 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 ללא עלות.
כברירת מחדל, ה-CLI של Firebase מנסה להשמיד אוטומטית גרסאות סודיות שאינן בשימוש במידת הצורך, כגון כאשר אתה פורס פונקציות עם גרסה חדשה של הסוד. כמו כן, אתה יכול לנקות באופן פעיל סודות שאינם בשימוש באמצעות functions:secrets:destroy
ו- functions:secrets:prune
.
Secret Manager מאפשר 10,000 פעולות גישה חודשיות ללא חיוב בסוד. מופעי פונקציות קוראים רק את הסודות שצוינו בפרמטר runWith
שלהם בכל פעם שהם מתחילים בקרה. אם יש לך הרבה מופעי פונקציות שקוראים הרבה סודות, הפרויקט שלך עלול לחרוג מהקצבה הזו, ובשלב זה תחויב ב-$0.03 לכל 10,000 פעולות גישה.
למידע נוסף, ראה תמחור מנהל סודי .
תמיכה באמולטור
תצורת הסביבה עם dotenv נועדה לפעול יחד עם אמולטור ענן פונקציות מקומי.
בעת שימוש באמולטור Cloud Functions מקומי, אתה יכול לעקוף משתני סביבה עבור הפרויקט שלך על ידי הגדרת קובץ .env.local
. התוכן של .env.local
עדיפות על .env
וקובץ ה- .env
הספציפי לפרויקט.
לדוגמה, פרויקט יכול לכלול את שלושת הקבצים האלה המכילים ערכים מעט שונים לפיתוח ובדיקות מקומיות:
.env | .env.dev | .env.local |
PLANET=כדור הארץ קהל=בני אדם | AUDIENCE=Dev Humans | קהל = בני אדם מקומיים |
כאשר מופעל בהקשר המקומי, האמולטור טוען את משתני הסביבה כפי שמוצג:
$ 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 ). ה-CLI של Firebase מספק פקודת ייצוא שמוציאה את התצורה של כל כינוי או פרויקט המופיעים בקובץ .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
במקום זאת, כפי שמוצג במשתני הסביבה .
תצורת סביבה
לפני שפורסמה תמיכת משתני סביבה ב- firebase-functions v3.18.0
, שימוש functions.config()
היה הגישה המומלצת לתצורת סביבה. גישה זו עדיין נתמכת, אך אנו ממליצים לכל הפרויקטים החדשים להשתמש במשתני סביבה במקום זאת, מכיוון שהם פשוטים יותר לשימוש ומשפרים את הניידות של הקוד שלך.
הגדר תצורת סביבה עם ה-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"
}
}
פונקציונליות זו מבוססת על Google Cloud Runtime Configuration API .
השתמש functions.config
כדי לגשת לתצורת הסביבה בפונקציה
תצורה מסויימת מסופקת אוטומטית תחת מרחב השמות השמור firebase
. תצורת הסביבה זמינה בתוך פונקציית ההפעלה שלך באמצעות functions.config()
. כדי להשתמש בתצורה שלמעלה, הקוד שלך עשוי להיראות כך:
const functions = require('firebase-functions');
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 מוכנים ללא כל תצורה. מודולים אחרים זקוקים לתצורה נוספת כדי לאתחל כהלכה. אנו ממליצים לאחסן את התצורה הזו במשתני תצורת הסביבה במקום לקודד אותה. זה עוזר לך לשמור על הקוד שלך הרבה יותר נייד, מה שמאפשר לך לפתוח את היישום שלך בקוד קוד או לעבור בקלות בין גרסאות ייצור ל-Staging.
לדוגמה, כדי להשתמש במודול Slack Node SDK , תוכל לכתוב את זה:
const functions = require('firebase-functions');
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://databaseName.firebaseio.com',
storageBucket: 'projectId.appspot.com',
projectId: 'projectId'
}
תצורה זו מוחלת באופן אוטומטי כאשר אתה מאתחל את Firebase Admin SDK ללא ארגומנטים. אם אתה כותב פונקציות ב-JavaScript, אתחול כך:
const admin = require('firebase-admin');
admin.initializeApp();
אם אתה כותב פונקציות ב-TypeScript, אתחול כך:
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import 'firebase-functions';
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 three 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.
- Runtime environment configuration with the Firebase CLI and
functions.config
.
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');
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.
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"})
Parameter types
Parameterized configuration provides strong typing for parameter values, and also support secrets from Cloud Secret Manager. Supported types are:
- Secret
- String
- Boolean
- Integer
- Float
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');
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');
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');
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');
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.
Environment variables
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
Reserved environment variables
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
- PORT
- 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. Specifically:
- 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 .
Emulator support
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 Environment variables .
Environment configuration
Before environment variable support was released in firebase-functions v3.18.0
, using functions.config()
was the recommended approach for environment configuration. This approach is still supported, but we recommend all new projects use environment variables instead, as they are simpler to use and improve the portability of your code.
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');
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');
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://databaseName.firebaseio.com',
storageBucket: 'projectId.appspot.com',
projectId: 'projectId'
}
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';
import * as admin from 'firebase-admin';
import 'firebase-functions';
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 three 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.
- Runtime environment configuration with the Firebase CLI and
functions.config
.
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');
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.
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"})
Parameter types
Parameterized configuration provides strong typing for parameter values, and also support secrets from Cloud Secret Manager. Supported types are:
- Secret
- String
- Boolean
- Integer
- Float
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');
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');
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');
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');
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.
Environment variables
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
Reserved environment variables
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
- PORT
- 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. Specifically:
- 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 .
Emulator support
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 Environment variables .
Environment configuration
Before environment variable support was released in firebase-functions v3.18.0
, using functions.config()
was the recommended approach for environment configuration. This approach is still supported, but we recommend all new projects use environment variables instead, as they are simpler to use and improve the portability of your code.
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');
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');
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://databaseName.firebaseio.com',
storageBucket: 'projectId.appspot.com',
projectId: 'projectId'
}
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';
import * as admin from 'firebase-admin';
import 'firebase-functions';
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);