הגדרת הסביבה


לעיתים קרובות תצטרכו הגדרות נוספות לפונקציות, כמו מפתחות API של צד שלישי או הגדרות שניתנות לכוונון. ‏SDK של Firebase ל-Cloud Functions מציע הגדרת סביבה מובנית כדי שיהיה קל לאחסן ולשלוף את סוג הנתונים הזה בפרויקט.

אפשר לבחור מבין האפשרויות הבאות:

  • הגדרה עם פרמטרים (מומלצת לרוב התרחישים). כך אפשר להגדיר סביבה עם סוגים מוגדרים מראש, עם פרמטרים שמאומתים בזמן הפריסה, וכך למנוע שגיאות ולפשט את תהליך ניפוי הבאגים.
  • הגדרה מבוססת-קבצים של משתני סביבה. בגישה הזו, יוצרים באופן ידני קובץ dotenv כדי לטעון את משתני הסביבה.

ברוב תרחישי השימוש מומלץ להשתמש בהגדרה עם פרמטרים. הגישה הזו מאפשרת לערכים של ההגדרות להיות זמינים גם במהלך זמן הריצה וגם בזמן הפריסה, והפריסה חסומה אלא אם לכל הפרמטרים יש ערך תקף. לעומת זאת, הגדרה באמצעות משתני סביבה לא זמינה בזמן הפריסה.

הגדרה עם פרמטרים

Cloud Functions for Firebase מספק ממשק להגדרת פרמטרים של הגדרה באופן הצהרתי בתוך ה-codebase שלכם. הערך של הפרמטרים האלה זמין גם במהלך פריסה של פונקציה, כשמגדירים את אפשרויות הפריסה והזמן הריצה, וגם במהלך הביצוע. כלומר, ה-CLI ייחסום את הפריסה אלא אם לכל הפרמטרים יהיה ערך תקין.

כדי להגדיר פרמטרים בקוד, פועלים לפי המודל הבא:

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

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

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

כשפורסים פונקציה עם משתני תצורה עם פרמטרים, ה-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> שנוצר לניהול הגרסאות.

שימוש בפרמטרים ברמת ה-global

במהלך הפריסה, קוד הפונקציות נטען ונבדק לפני שלפרמטרים יש ערכים בפועל. כלומר, אחזור של ערכי פרמטרים ברמת ההיקף הגלובלי גורם לכישלון הפריסה. במקרים שבהם רוצים להשתמש בפרמטר כדי לאתחל ערך גלובלי, אפשר להשתמש בקריאה החוזרת (callback) של האתחול onInit(). הקריאה החוזרת (callback) הזו פועלת לפני הרצה של פונקציות בסביבת הייצור, אבל לא מתבצעת קריאה אליהן בזמן הפריסה, ולכן היא מקום בטוח לגישה לערך של הפרמטר.

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

  const apiKey = defineSecret('GOOGLE_API_KEY');

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

הגדרת ההתנהגות של ה-CLI

אפשר להגדיר את הפרמטרים באמצעות אובייקט Options שקובע איך ה-CLI יבקש ערכים. בדוגמה הבאה מוגדר אימות של הפורמט של מספר הטלפון, אפשרות בחירה פשוטה ויישוב אוטומטי של אפשרות בחירה מהפרויקט ב-Firebase:

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

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

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

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

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

סוגי פרמטרים

הגדרה עם פרמטרים מספקת סוגים חזקים לערכים של פרמטרים, ותומכת גם בסודות מ-Cloud Secret Manager. הסוגים הנתמכים הם:

  • סודי
  • String
  • בוליאני
  • מספר שלם
  • Float

ערכים וביטויים של פרמטרים

מערכת Firebase מעריכה את הפרמטרים גם בזמן הפריסה וגם בזמן ההפעלה של הפונקציה. בגלל הסביבות הכפולות האלה, צריך להיזהר כשמשווים בין ערכי הפרמטרים, וכשמשתמשים בהם כדי להגדיר אפשרויות בסביבת זמן הריצה של הפונקציות.

כדי להעביר פרמטר לפונקציה כאפשרות בסביבת זמן ריצה, צריך להעביר אותו ישירות:

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

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

בנוסף, אם אתם צריכים להשוות לערך של פרמטר כדי לדעת איזו אפשרות לבחור, תצטרכו להשתמש במנגנוני השוואה מובנים במקום לבדוק את הערך:

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

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

אפשר לגשת לפרמטר ולביטוי הפרמטר שמשמשים רק במהלך זמן הריצה באמצעות הפונקציה value:

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

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

פרמטרים מובְנים

ב-Cloud Functions SDK יש שלושה פרמטרים מוגדרים מראש, שזמינים בחבילת המשנה firebase-functions/params:

  • projectID – הפרויקט ב-Cloud שבו הפונקציה פועלת.
  • databaseURL – כתובת ה-URL של המכונה של 'מסד נתונים בזמן אמת' שמשויכת לפונקציה (אם היא הופעלה בפרויקט Firebase).
  • storageBucket – הקטגוריה של Cloud Storage שמשויכת לפונקציה (אם היא מופעלת בפרויקט ב-Firebase).

הם פועלים כמו פרמטרים של מחרוזות שהוגדרו על ידי משתמשים מכל הבחינות, מלבד העובדה שמכיוון שהערכים שלהם תמיד ידועים ל-CLI של Firebase, אף פעם לא תופיע בקשה להזין את הערכים שלהם בזמן הפריסה, והם גם לא יישמרו בקובצי .env.

פרמטרים של סודות

פרמטרים מסוג Secret, שמוגדרים באמצעות defineSecret(), מייצגים פרמטרים של מחרוזת שיש להם ערך שמאוחסן ב-Cloud Secret Manager. במקום לבדוק בקובץ .env המקומי ולכתוב ערך חדש לקובץ אם הוא חסר, הפרמטרים הסודיים בודקים אם הסוד קיים ב-Cloud Secret Manager, ומבקשים באופן אינטראקטיבי את הערך של סוד חדש במהלך הפריסה.

פרמטרים סודיים שמוגדרים כך חייבים להיות מקושרים לפונקציות נפרדות שצריכה להיות להן גישה אליהם:

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

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

מכיוון שהערכים של הסודות מוסתרים עד להפעלת הפונקציה, אי אפשר להשתמש בהם כשמגדירים את הפונקציה.

משתני סביבה

Cloud Functions for Firebase תומך בפורמט הקובץ dotenv לטעינת משתני סביבה שצוינו בקובץ .env בסביבת זמן הריצה של האפליקציה. אחרי שפורסים את משתני הסביבה, אפשר לקרוא אותם דרך הממשק של process.env.

כדי להגדיר את הסביבה בדרך הזו, יוצרים קובץ .env בפרויקט, מוסיפים את המשתנים הרצויים ופורסים:

  1. יוצרים קובץ .env בספרייה functions/:

    # Directory layout:
    #   my-project/
    #     firebase.json
    #     functions/
    #       .env
    #       package.json
    #       index.js
    
  2. פותחים את הקובץ .env לעריכה ומוסיפים את המפתחות הרצויים. לדוגמה:

    PLANET=Earth
    AUDIENCE=Humans
    
  3. פריסת פונקציות ואימות שמשתני הסביבה נטענו:

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

אחרי שפורסים את משתני הסביבה המותאמים אישית, קוד הפונקציה יכול לגשת אליהם באמצעות תחביר process.env:

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

פריסה של מספר קבוצות של משתני סביבה

אם אתם צריכים קבוצה חלופית של משתני סביבה לפרויקטים ב-Firebase (למשל Staging לעומת סביבת הייצור), יוצרים קובץ .env.<project or alias> וכותבים בו את משתני הסביבה הספציפיים לפרויקט. משתני הסביבה מקובץ .env ומקבצים .env ספציפיים לפרויקט (אם הם קיימים) ייכללו בכל הפונקציות שנפרסות.

לדוגמה, פרויקט יכול לכלול את שלושת הקבצים הבאים, עם ערכים מעט שונים לצורכי פיתוח וייצור:

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

AUDIENCE=Humans

AUDIENCE=Dev בני אדם 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
  • GCLOUD_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

אחסון מידע רגיש של הגדרות אישיות וגישה אליו

אפשר להשתמש במשתני הסביבה ששמורים בקובצי .env להגדרת פונקציות, אבל לא כדאי להתייחס אליהם כדרך מאובטחת לאחסון מידע רגיש, כמו פרטי כניסה של מסד נתונים או מפתחות API. זה חשוב במיוחד אם בודקים את קובצי .env דרך בקרת המקור.

כדי לעזור לכם לאחסן מידע רגיש של הגדרות, Cloud Functions for Firebase משתלב עם Google Cloud Secret Manager. השירות המוצפן הזה מאחסן את ערכי ההגדרות בצורה מאובטחת, ועדיין מאפשר גישה קלה מהפונקציות שלכם במקרה הצורך.

יצירה של סוד ושימוש בו

כדי ליצור סוד, משתמשים ב-CLI של Firebase.

כדי ליצור סוד ולהשתמש בו:

  1. מריצים את הפקודה הבאה מהשורש של ספריית הפרויקט המקומית:

    firebase functions:secrets:set SECRET_NAME

  2. מזינים ערך בשדה SECRET_NAME.

    ה-CLI משדר הודעת הצלחה ומזהיר אתכם שצריך לפרוס פונקציות כדי שהשינוי ייכנס לתוקף.

  3. לפני הפריסה, צריך לוודא שקוד הפונקציות מאפשר לפונקציה לגשת לסוד באמצעות הפרמטר runWith:

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

    firebase deploy --only functions

עכשיו תוכלו לגשת אליו כמו לכל משתנה סביבה אחר. לעומת זאת, אם פונקציה אחרת שלא מציינת את הסוד ב-runWith תנסה לגשת אליו, היא תקבל ערך לא מוגדר:

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

אחרי שהפונקציה פרוסה, תהיה לה גישה לערך הסוד. רק פונקציות שכוללות באופן ספציפי סוד בפרמטרים שלהן runWith תהיה גישה לסוד הזה כמשתנה סביבה. כך תוכלו לוודא שערכים סודיים זמינים רק כשהם נחוצים, וכך לצמצם את הסיכון להדלפה בטעות של סוד.

ניהול סודות

משתמשים בממשק CLI של Firebase כדי לנהל את הסודות. כשמנהלים סודות בדרך הזו, חשוב לזכור שחלק מהשינויים ב-CLI מחייבים לשנות או לפרוס מחדש את הפונקציות המשויכות. באופן ספציפי:

  • בכל פעם שמגדירים ערך חדש לסוד, צריך לפרוס מחדש את כל הפונקציות שמפנות לסוד הזה כדי שהן יקבלו את הערך העדכני.
  • אם מוחקים סוד, צריך לוודא שאף אחת מהפונקציות שנפרסו לא מפנה לסוד הזה. פונקציות שמשתמשות בערך סודי שנמחק ייכשלו באופן שקט.

סיכום של פקודות ה-CLI של Firebase לניהול סודות:

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

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

# Destroy a secret
functions:secrets:destroy SECRET_NAME

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

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

בפקודות access ו-destroy, אפשר לציין את הפרמטר האופציונלי version כדי לנהל גרסה מסוימת. לדוגמה:

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 בכל פעם שהן מופעלות במצב התחלתי (cold start). אם יש הרבה מכונות של פונקציות שקוראות הרבה סודות, יכול להיות שהפרויקט יחרוג מההקצבה הזו, ובשלב הזה תחויבו ב-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 בני אדם 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 תומך בשימוש בסודות כדי לאחסן ולגשת למידע רגיש של הגדרות. כברירת מחדל, הסימולטור ינסה לגשת לסודות הייצור באמצעות Application Default Credentials. במצבים מסוימים כמו סביבות 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 במקום זאת, כפי שמתואר בקטע שדרוג לדור השני.

הגדרת הסביבה

הגדרת התצורה של הסביבה באמצעות CLI

כדי לאחסן נתוני סביבה, אפשר להשתמש בפקודה firebase functions:config:set ב-CLI של Firebase. אפשר למרחב שמות של כל מפתח באמצעות נקודות כדי לקבץ יחד הגדרות אישיות קשורות. חשוב לזכור שבמקשים אפשר להשתמש רק באותיות קטנות, ובאותיות רישיות אי אפשר להשתמש באותיות רישיות.

לדוגמה, כדי לאחסן את מזהה הלקוח ומפתח ה-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/v1');
const request = require('request-promise');

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

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

שימוש בהגדרת הסביבה כדי לאתחל מודול

חלק מהמודולים של Node מוכנים לשימוש בלי הגדרות. במודולים אחרים נדרשת הגדרה נוספת כדי לבצע את האינטוליזציה בצורה נכונה. מומלץ לאחסן את ההגדרות האישיות האלה במשתנים של הגדרת הסביבה, ולא בקוד שלהן. כך תוכלו לשמור על ניידות הקוד שלכם באופן משמעותי, וכך תוכלו להשתמש באפליקציה בקוד פתוח או לעבור בקלות בין גרסאות ייצור לבין גרסאות Staging.

לדוגמה, כדי להשתמש במודול Slack Node SDK, אפשר לכתוב את הקוד הבא:

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

לפני הפריסה, מגדירים את משתנה התצורה של הסביבה slack.url:

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

פקודות נוספות לגבי סביבה

  • firebase functions:config:unset key1 key2 מסיר את המפתחות שצוינו מהתצורה
  • firebase functions:config:clone --from <fromProject> משכפל סביבה של פרויקט אחר לפרויקט הפעיל הנוכחי.

משתני סביבה שמולאו באופן אוטומטי

יש משתני סביבה שמאוכלסים באופן אוטומטי בזמן הריצה של הפונקציות ובפונקציות האמולציה מקומית. הם כוללים את אלה שאוכלסו על ידי Google Cloud, וגם משתנה סביבה ספציפי ל-Firebase:

process.env.FIREBASE_CONFIG: מספקת את פרטי ההגדרות הבאים של פרויקט Firebase:

{
  databaseURL: 'https://databaseName.firebaseio.com',
  storageBucket: 'projectId.appspot.com',
  projectId: 'projectId'
}

ההגדרה הזו מוחלת באופן אוטומטי כשמאתחלים את ה-SDK של Firebase Admin ללא ארגומנטים. אם כותבים פונקציות ב-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();

אם אתם צריכים לאתחל את 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);