במקרים רבים צריך להגדיר הגדרות נוספות לפונקציות, כמו מפתחות API של צד שלישי או הגדרות שניתן לשנות. ערכת ה-SDK של Firebase ל-Cloud Functions כוללת הגדרת סביבה מובנית, שמאפשרת לאחסן ולאחזר בקלות את סוג הנתונים הזה בפרויקט.
אפשר לבחור מבין האפשרויות הבאות:
- הגדרה עם פרמטרים (מומלצת ברוב המקרים). כך מקבלים הגדרת סביבה עם סוגים מוגדרים היטב ופרמטרים שעוברים אימות בזמן הפריסה, מה שמונע שגיאות ומפשט את ניפוי הבאגים.
- הגדרה מבוססת-קובץ של משתני סביבה. בגישה הזו, יוצרים ידנית קובץ dotenv כדי לטעון משתני סביבה.
ברוב המקרים, מומלץ להשתמש בהגדרות עם פרמטרים. בגישה הזו, ערכי ההגדרות זמינים גם בזמן הריצה וגם בזמן הפריסה, והפריסה נחסמת אלא אם לכל הפרמטרים יש ערך תקין. לעומת זאת, אי אפשר להגדיר משתני סביבה בזמן הפריסה.
הגדרה עם פרמטרים
Cloud Functions for Firebase מספק ממשק להגדרת פרמטרים של הגדרות אישיות באופן הצהרתי בתוך בסיס הקוד. הערך של הפרמטרים האלה זמין גם במהלך פריסת הפונקציה, כשמגדירים את אפשרויות הפריסה וזמן הריצה, וגם במהלך ההפעלה. כלומר, ה-CLI יחסום את הפריסה אם לא כל הפרמטרים מכילים ערך תקין.
Node.js
const { onRequest } = require('firebase-functions/v2/https');
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 = onRequest(
{ minInstances: minInstancesConfig },
(req, res) => {
res.send(`${welcomeMessage.value()}! I am a function.`);
}
);
Python
from firebase_functions import https_fn
from firebase_functions.params import IntParam, StringParam
MIN_INSTANCES = IntParam("HELLO_WORLD_MIN_INSTANCES")
WELCOME_MESSAGE = StringParam("WELCOME_MESSAGE")
# To use configured parameters inside the config for a function, provide them
# directly. To use them at runtime, call .value() on them.
@https_fn.on_request(min_instances=MIN_INSTANCES)
def hello_world(req):
return https_fn.Response(f'{WELCOME_MESSAGE.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(). הקריאה החוזרת הזו פועלת לפני שפונקציות כלשהן פועלות בסביבת הייצור, אבל לא מתבצעת קריאה אליה במהלך הפריסה, כך שזה מקום בטוח לגשת לערך של פרמטר.
Node.js
const { GoogleGenerativeAI } = require('@google/generative-ai');
const { defineSecret } = require('firebase-functions/params');
const { onInit } = require('firebase-functions/v2/core');
const apiKey = defineSecret('GOOGLE_API_KEY');
let genAI;
onInit(() => {
genAI = new GoogleGenerativeAI(apiKey.value());
})
Python
from firebase_functions.core import init
from firebase_functions.params import StringParam, PROJECT_ID
import firebase_admin
import vertexai
location = StringParam("LOCATION")
x = "hello"
@init
def initialize():
# Note: to write back to a global, you'll need to use the "global" keyword
# to avoid creating a new local with the same name.
global x
x = "world"
firebase_admin.initialize_app()
vertexai.init(PROJECT_ID.value, location.value)
אם אתם משתמשים בפרמטרים מסוג Secret, שימו לב שהם זמינים רק בתהליך של פונקציות שקשורות לסוד. אם סוד מקושר רק בחלק מהפונקציות, צריך לבדוק אם secret.value() הוא falsy לפני שמשתמשים בו.
הגדרת אופן הפעולה של ה-CLI
אפשר להגדיר פרמטרים באמצעות אובייקט Options שקובע איך ה-CLI יבקש ערכים. בדוגמה הבאה מוגדרות אפשרויות לאימות הפורמט של מספר טלפון, להצגת אפשרות בחירה פשוטה ולאכלוס אוטומטי של אפשרות בחירה מהפרויקט ב-Firebase:
Node.js
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: params.select(["odd", "even"])});
const memory = defineInt("MEMORY", {
description: "How much memory do you need?",
input: params.select({ "micro": 256, "chonky": 2048 }),
});
const extensions = defineList("EXTENSIONS", {
description: "Which file types should be processed?",
input: params.multiSelect(["jpg", "tiff", "png", "webp"]),
});
const storageBucket = defineString('BUCKET', {
description: "This will automatically
populate the selector field with the deploying Cloud Project’s
storage buckets",
input: params.PICK_STORAGE_BUCKET,
});
Python
from firebase_functions.params import (
StringParam,
ListParam,
TextInput,
SelectInput,
SelectOptions,
ResourceInput,
ResourceType,
)
MIN_INSTANCES = IntParam("HELLO_WORLD_MIN_INSTANCES")
WELCOME_MESSAGE = StringParam(
"WELCOME_MESSAGE",
default="Hello World",
description="The greeting that is returned to the caller of this function",
)
ONLY_PHONE_NUMBERS = StringParam(
"PHONE_NUMBER",
input=TextInput(
validation_regex="\d{3}-\d{3}-\d{4}",
validation_error_message="Please enter a phone number in the format XXX-YYY-XXX",
),
)
SELECT_OPTION = StringParam(
"PARITY",
input=SelectInput([SelectOptions(value="odd"), SelectOptions(value="even")]),
)
STORAGE_BUCKET = StringParam(
"BUCKET",
input=ResourceInput(type=ResourceType.STORAGE_BUCKET),
description="This will automatically populate the selector field with the deploying Cloud Project's storage buckets",
)
סוגי פרמטרים
הגדרות עם פרמטרים מספקות הקלדה חזקה של ערכי פרמטרים, וגם תומכות בסודות מ-Cloud Secret Manager. הסוגים הנתמכים הם:
- סודי
- מחרוזת
- בוליאני
- מספר שלם
- Float
- רשימה (Node.js)
- JSON Secret (Node.js)
בהפניה למרחב השמות params מוסבר על הפונקציות להגדרת פרמטרים.
ערכי פרמטרים וביטויים
מערכת Firebase מעריכה את הפרמטרים גם בזמן הפריסה וגם בזמן שהפונקציה פועלת. בגלל הסביבות הכפולות האלה, צריך לשים לב כשמשווים בין ערכי פרמטרים וכשמשתמשים בהם כדי להגדיר אפשרויות של סביבת זמן ריצה לפונקציות.
כדי להעביר פרמטר לפונקציה כאפשרות של זמן ריצה, מעבירים אותו ישירות:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const { defineInt } = require('firebase-functions/params');
const minInstancesConfig = defineInt('HELLO_WORLD_MININSTANCES');
export const helloWorld = onRequest(
{ minInstances: minInstancesConfig },
(req, res) => {
//…
Python
from firebase_functions import https_fn
from firebase_functions.params import IntParam
MIN_INSTANCES = IntParam("HELLO_WORLD_MIN_INSTANCES")
@https_fn.on_request(min_instances=MIN_INSTANCES)
def hello_world(req):
...
בנוסף, אם אתם צריכים להשוות לפרמטר כדי לדעת באיזו אפשרות לבחור, תצטרכו להשתמש בפונקציות השוואה מובנות במקום לבדוק את הערך:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const environment = params.defineString(‘ENVIRONMENT’, {default: 'dev'});
// use built-in comparators
const minInstancesConfig = environment.equals('PRODUCTION').thenElse(10, 1);
export const helloWorld = onRequest(
{ minInstances: minInstancesConfig },
(req, res) => {
//…
Python
from firebase_functions import https_fn
from firebase_functions.params import IntParam, StringParam
ENVIRONMENT = StringParam("ENVIRONMENT", default="dev")
MIN_INSTANCES = ENVIRONMENT.equals("PRODUCTION").then(10, 0)
@https_fn.on_request(min_instances=MIN_INSTANCES)
def hello_world(req):
...
אפשר לגשת לפרמטרים ולביטויי פרמטרים שמשמשים רק בזמן הריצה באמצעות הפונקציה value שלהם:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
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 = onRequest(
(req, res) => {
res.send(`${welcomeMessage.value()}! I am a function.`);
}
);
Python
from firebase_functions import https_fn
from firebase_functions.params import StringParam
WELCOME_MESSAGE = StringParam("WELCOME_MESSAGE")
@https_fn.on_request()
def hello_world(req):
return https_fn.Response(f'{WELCOME_MESSAGE.value()}! I am a function!')
פרמטרים מובנים
ב-Cloud Functions SDK יש שלושה פרמטרים מוגדרים מראש, שזמינים מחבילת המשנה firebase-functions/params:
Node.js
-
projectID– הפרויקט בענן שבו הפונקציה פועלת. -
databaseURL– כתובת ה-URL של המכונה של מסד הנתונים בזמן אמת שמשויכת לפונקציה (אם היא מופעלת בפרויקט ב-Firebase). -
storageBucket– הקטגוריה של Cloud Storage שמשויכת לפונקציה (אם היא מופעלת בפרויקט Firebase).
Python
-
PROJECT_ID– הפרויקט בענן שבו הפונקציה פועלת. -
DATABASE_URL– כתובת ה-URL של המכונה של מסד הנתונים בזמן אמת שמשויכת לפונקציה (אם היא מופעלת בפרויקט ב-Firebase). -
STORAGE_BUCKET– הקטגוריה של Cloud Storage שמשויכת לפונקציה (אם היא מופעלת בפרויקט Firebase).
הם פועלים כמו פרמטרים של מחרוזות שמוגדרים על ידי המשתמשים, אבל מכיוון שהערכים שלהם תמיד ידועים ל-Firebase CLI, הערכים שלהם אף פעם לא יתבקשו בפריסה ולא יישמרו בקובצי .env.
פרמטרים סודיים
פרמטרים מסוג Secret, שמוגדרים באמצעות defineSecret(), מייצגים פרמטרים של מחרוזת שהערך שלהם מאוחסן ב-Cloud Secret Manager. במקום לבדוק קובץ .env מקומי ולכתוב ערך חדש בקובץ אם הוא חסר, הפרמטרים הסודיים בודקים אם הוא קיים ב-Cloud Secret Manager, ומבקשים באופן אינטראקטיבי את הערך של סוד חדש במהלך הפריסה.
צריך לקשר פרמטרים סודיים לפונקציות ספציפיות שאמורות לקבל גישה אליהם:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const { defineSecret } = require('firebase-functions/params');
const discordApiKey = defineSecret('DISCORD_API_KEY');
export const postToDiscord = onRequest(
{ secrets: [discordApiKey] },
(req, res) => {
const apiKey = discordApiKey.value();
//…
Python
from firebase_functions import https_fn
from firebase_functions.params import SecretParam
DISCORD_API_KEY = SecretParam('DISCORD_API_KEY')
@https_fn.on_request(secrets=[DISCORD_API_KEY])
def post_to_discord(req):
api_key = DISCORD_API_KEY.value
הערכים של הסודות מוסתרים עד להפעלת הפונקציה, ולכן אי אפשר להשתמש בהם בזמן הגדרת הפונקציה.
סודות JSON מובנים
אם יש לכם כמה ערכי הגדרות שקשורים באופן לוגי (לדוגמה, הגדרות של שירות צד שלישי), אתם יכולים לאחסן אותם ביחד כאובייקט JSON מובנה בתוך סוד אחד באמצעות defineJsonSecret(). הגישה הזו יכולה לעזור לכם לארגן את ההגדרות ולהשתמש בצורה יעילה יותר בתוכנית בחינם של Cloud Secret Manager, על ידי אחסון קבוצה של ערכי הגדרות קשורים בסוד אחד.
הערך שמאוחסן ב-Secret Manager חייב להיות מחרוזת JSON תקינה. ה-SDK ינתח באופן אוטומטי את מחרוזת ה-JSON לאובייקט ב-JavaScript כשתיגשו אל .value().
לדוגמה:
const { onRequest } = require('firebase-functions/v2/https');
const { defineJsonSecret } = require('firebase-functions/params');
// Define a single secret to hold all configuration for some API
const someApiConfig = defineJsonSecret('SOMEAPI_CONFIG');
exports.myApi = onRequest(
{ secrets: [someApiConfig] },
(req, res) => {
// someApiConfig.value() automatically parses the JSON secret
const { apiKey, webhookSecret, clientId } = someApiConfig.value();
// Now you can use apiKey, webhookSecret, clientId
// ...
}
);
כדי ליצור את הסוד SOMEAPI_CONFIG, צריך להגדיר את הערך שלו ב-Secret Manager למחרוזת JSON, למשל:
{
"apiKey": "key_...",
"webhookSecret": "secret_...",
"clientId": "client_..."
}
אם ערך הסוד הוא לא JSON תקין, הגישה אל someApiConfig.value() תגרום לשגיאה בזמן הריצה.
משתני סביבה
Cloud Functions for Firebase תומך בפורמט הקובץ dotenv כדי לטעון משתני סביבה שצוינו בקובץ .env לזמן הריצה של האפליקציה. אחרי הפריסה, אפשר לקרוא את משתני הסביבה באמצעות הממשק process.env (בפרויקטים שמבוססים על Node.js) או os.environ (בפרויקטים שמבוססים על Python).
כדי להגדיר את הסביבה בדרך הזו, יוצרים קובץ .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. # ...
אחרי שפורסים את משתני הסביבה בהתאמה אישית, אפשר לגשת אליהם באמצעות קוד הפונקציה:
Node.js
// Responds with "Hello Earth and Humans"
exports.hello = onRequest((request, response) => {
response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});
Python
import os
@https_fn.on_request()
def hello(req):
return https_fn.Response(
f"Hello {os.environ.get('PLANET')} and {os.environ.get('AUDIENCE')}"
)
פריסה של כמה קבוצות של משתני סביבה
אם אתם צריכים קבוצה חלופית של משתני סביבה לפרויקטים ב-Firebase (למשל, סביבת Staging לעומת סביבת ייצור), אתם יכולים ליצור קובץ .env.<project or
alias> ולכתוב בו את משתני הסביבה הספציפיים לפרויקט. משתני הסביבה מהקובץ .env ומהקובץ .env הספציפי לפרויקט (אם הם קיימים) ייכללו בכל הפונקציות שנפרסו.
לדוגמה, פרויקט יכול לכלול את שלושת הקבצים הבאים שמכילים ערכים שונים במקצת לפיתוח ולייצור:
.env
|
.env.dev
|
.env.prod
|
| PLANET=Earth
AUDIENCE=Humans |
AUDIENCE=Dev Humans | AUDIENCE=Prod 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
- 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. השירות המוצפן הזה מאחסן ערכי הגדרות אישיות בצורה מאובטחת, ועדיין מאפשר גישה קלה מהפונקציות שלכם כשצריך.
יצירת סוד ושימוש בו
כדי ליצור סוד, משתמשים ב-CLI של Firebase.
כדי ליצור סוד ולהשתמש בו:
מהרמה הבסיסית (root) של ספריית הפרויקט המקומית, מריצים את הפקודה הבאה:
firebase functions:secrets:set SECRET_NAME
צריך להזין ערך בשדה SECRET_NAME.
ב-CLI תוצג הודעת הצלחה ואזהרה שצריך לפרוס את הפונקציות כדי שהשינוי ייכנס לתוקף.
לפני הפריסה, ודאו שקוד הפונקציות מאפשר לפונקציה לגשת לסוד באמצעות האפשרות
secrets:Node.js
const { onRequest } = require('firebase-functions/v2/https'); exports.processPayment = onRequest( { secrets: ["SECRET_NAME"] }, (req, res) => { const myBillingService = initializeBillingService( // reference the secret value process.env.SECRET_NAME ); // Process the payment } );Python
import os from firebase_functions import https_fn @https_fn.on_request(secrets=["SECRET_NAME"]) def process_payment(req): myBillingService = initialize_billing(key=os.environ.get('SECRET_NAME')) # Process the payment ...פריסת Cloud Functions:
firebase deploy --only functions
עכשיו תוכלו לגשת אליו כמו לכל משתנה סביבה אחר. לעומת זאת, אם פונקציה אחרת שלא מציינת את הסוד מנסה לגשת אליו, היא מקבלת ערך לא מוגדר:
Node.js
exports.anotherEndpoint = onRequest((request, response) => { response.send(`The secret API key is ${process.env.SECRET_NAME}`); // responds with "The secret API key is undefined" because the `secrets` option is missing });Python
@https_fn.on_request() def another_endpoint(req): return https_fn.Response(f"The secret API key is {os.environ.get("SECRET_NAME")}") # Responds with "The secret API key is None" because the `secrets` parameter is missing.
אחרי שפורסים את הפונקציה, יש לה גישה לערך הסודי. רק לפונקציות שכוללות באופן ספציפי סוד באפשרות secrets תהיה גישה לסוד הזה כמשתנה סביבה. כך אתם יכולים לוודא שערכי הסודות זמינים רק במקומות שבהם הם נדרשים, ולהפחית את הסיכון לדליפה מקרית של סוד.
ניהול סודות
משתמשים ב-CLI של Firebase כדי לנהל את הסודות. כשמנהלים סודות בדרך הזו, חשוב לזכור שחלק מהשינויים ב-CLI מחייבים לשנות או לפרוס מחדש את הפונקציות המשויכות. באופן ספציפי:
- בכל פעם שאתם מגדירים ערך חדש לסוד, אתם צריכים לפרוס מחדש את כל הפונקציות שמפנות לסוד הזה כדי שהן יקבלו את הערך העדכני.
- אם אתם מוחקים סוד, ודאו שאף אחת מהפונקציות שפרסתם לא מפנה לסוד הזה. פונקציות שמשתמשות בערך סודי שנמחק ייכשלו בלי להציג הודעת שגיאה.
ריכזנו כאן סיכום של פקודות ה-CLI של Firebase לניהול סודות:
# Change the value of an existing secret firebase functions:secrets:set SECRET_NAME # Set secret from file firebase functions:secrets:set SECRET_NAME --data-file file.json # Validate secret value as json cat file.json | firebase functions:secrets:set SECRET_NAME --format=json # Pipe from stdin and set secret cat file.json | firebase functions:secrets:set SECRET_NAME --format=json # 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 פעולות גישה חודשיות ללא חיוב לסוד. מופעי הפונקציות קוראים רק את הסודות שצוינו באפשרות secrets בכל פעם שהם מופעלים בהפעלה קרה. אם יש לכם הרבה מופעי פונקציות שקוראים הרבה סודות, יכול להיות שהפרויקט שלכם יחרוג מהמכסה הזו, ואז תחויבו ב-0.03 $לכל 10,000 פעולות גישה.
מידע נוסף זמין במאמר התמחור של Secret Manager.
תמיכה באמולטורים
הגדרת הסביבה באמצעות dotenv נועדה לפעול בשילוב עם אמולטור Cloud Functions מקומי.
כשמשתמשים באמולטור Cloud Functions מקומי, אפשר לשנות את משתני הסביבה של הפרויקט על ידי הגדרת קובץ .env.local. התוכן של .env.local מקבל עדיפות על פני .env ועל פני הקובץ .env הספציפי לפרויקט.
לדוגמה, פרויקט יכול לכלול את שלושת הקבצים הבאים, שמכילים ערכים שונים במקצת לפיתוח ולבדיקה מקומית:
.env
|
.env.dev
|
.env.local
|
| PLANET=Earth
AUDIENCE=Humans |
AUDIENCE=Dev Humans | AUDIENCE=Local 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. כך קל לבדוק את הפונקציות באופן מקומי, במיוחד אם אין לכם גישה לערך הסודי.
מעבר מהגדרת סביבת זמן ריצה
ה-API של functions.config הוצא משימוש ויושבת במרץ 2027.
אחרי התאריך הזה, פריסות עם functions.config ייכשלו.
כדי למנוע כשלים בפריסה, צריך להעביר את ההגדרות האישיות ל-Cloud Secret Manager באמצעות ה-CLI של Firebase. מומלץ מאוד להשתמש בשיטה הזו, כי היא הדרך היעילה והבטוחה ביותר להעביר את ההגדרות האישיות.
הגדרות אישיות של ייצוא באמצעות ה-CLI של Firebase
משתמשים בפקודה
config exportכדי לייצא את הגדרת הסביבה הקיימת לסוד חדש ב-Cloud Secret Manager:$ firebase functions:config:export i This command retrieves your Runtime Config values (accessed via functions.config()) and exports them as a Secret Manager secret. i Fetching your existing functions.config() from your project... ✔ Fetched your existing functions.config(). i Configuration to be exported: ⚠ This may contain sensitive data. Do not share this output. { ... } ✔ What would you like to name the new secret for your configuration? RUNTIME_CONFIG ✔ Created new secret version projects/project/secrets/RUNTIME_CONFIG/versions/1```עדכון קוד הפונקציה כדי לקשר סודות
כדי להשתמש בהגדרות האישיות ששמורות בסוד החדש ב-Cloud Secret Manager, צריך להשתמש ב-API של
defineJsonSecretבקוד המקור של הפונקציה. בנוסף, חשוב לוודא שהסודות מקושרים לכל הפונקציות שצריכות אותם.לפני
const functions = require("firebase-functions/v1"); exports.myFunction = functions.https.onRequest((req, res) => { const apiKey = functions.config().someapi.key; // ... });אחרי
const { onRequest } = require("firebase-functions/v2/https"); const { defineJsonSecret } = require("firebase-functions/params"); const config = defineJsonSecret("RUNTIME_CONFIG"); exports.myFunction = onRequest( // Bind secret to your function { secrets: [config] }, (req, res) => { // Access secret values via .value() const apiKey = config.value().someapi.key; // ... });פריסת פונקציות
פורסים את הפונקציות המעודכנות כדי להחיל את השינויים ולקשר את ההרשאות לסוד.
firebase deploy --only functions:<your-function-name>
משתני סביבה שמאוכלסים באופן אוטומטי
יש משתני סביבה שמאוכלסים באופן אוטומטי בסביבת זמן הריצה של הפונקציות ובפונקציות שמדמים באופן מקומי. הם כוללים את אלה שמאוכלסים על ידי Google Cloud, וגם משתנה סביבה ספציפי ל-Firebase:
process.env.FIREBASE_CONFIG: מספק את פרטי ההגדרה הבאים של פרויקט Firebase:
{
databaseURL: 'https://DATABASE_NAME.firebaseio.com',
storageBucket: 'PROJECT_ID.firebasestorage.app ',
projectId: 'PROJECT_ID'
}
שימו לב שהערכים בהגדרות בפועל של Firebase עשויים להשתנות בהתאם למשאבים שהקציתם בפרויקט.
ההגדרה הזו מופעלת באופן אוטומטי כשמפעילים את ה-SDK של 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 לאדמינים עם הגדרת ברירת המחדל של הפרויקט באמצעות פרטי כניסה לחשבון שירות, אתם יכולים לטעון את פרטי הכניסה מקובץ ולהוסיף אותם ל-FIREBASE_CONFIG באופן הבא:
serviceAccount = require('./serviceAccount.json');
const adminConfig = JSON.parse(process.env.FIREBASE_CONFIG);
adminConfig.credential = admin.credential.cert(serviceAccount);
admin.initializeApp(adminConfig);