תחילת העבודה: כתיבה, בדיקה ופריסה של הפונקציות הראשונות

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

  • פונקציה של "הוספת הודעה" שחושפת כתובת URL שמקבלת ערך טקסט וכותבת אותו ב-Cloud Firestore.
  • פונקציה של "הפיכה לאותיות רישיות" שמופעלת בכתיבה של Cloud Firestore והופכת את הטקסט לאותיות רישיות.

הנה הקוד לדוגמה המלא שמכיל את הפונקציות:

Node.js

// The Cloud Functions for Firebase SDK to create Cloud Functions and triggers.
const {logger} = require("firebase-functions");
const {onRequest} = require("firebase-functions/https");
const {onDocumentCreated} = require("firebase-functions/firestore");

// The Firebase Admin SDK to access Firestore.
const {initializeApp} = require("firebase-admin/app");
const {getFirestore} = require("firebase-admin/firestore");

initializeApp();

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addmessage = onRequest(async (req, res) => {
  // Grab the text parameter.
  const original = req.query.text;
  // Push the new message into Firestore using the Firebase Admin SDK.
  const writeResult = await getFirestore()
      .collection("messages")
      .add({original: original});
  // Send back a message that we've successfully written the message
  res.json({result: `Message with ID: ${writeResult.id} added.`});
});

// Listens for new messages added to /messages/:documentId/original
// and saves an uppercased version of the message
// to /messages/:documentId/uppercase
exports.makeuppercase = onDocumentCreated("/messages/{documentId}", (event) => {
  // Grab the current value of what was written to Firestore.
  const original = event.data.data().original;

  // Access the parameter `{documentId}` with `event.params`
  logger.log("Uppercasing", event.params.documentId, original);

  const uppercase = original.toUpperCase();

  // You must return a Promise when performing
  // asynchronous tasks inside a function
  // such as writing to Firestore.
  // Setting an 'uppercase' field in Firestore document returns a Promise.
  return event.data.ref.set({uppercase}, {merge: true});
});

Python

# The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
from firebase_functions import firestore_fn, https_fn

# The Firebase Admin SDK to access Cloud Firestore.
from firebase_admin import initialize_app, firestore
import google.cloud.firestore

app = initialize_app()


@https_fn.on_request()
def addmessage(req: https_fn.Request) -> https_fn.Response:
    """Take the text parameter passed to this HTTP endpoint and insert it into
    a new document in the messages collection."""
    # Grab the text parameter.
    original = req.args.get("text")
    if original is None:
        return https_fn.Response("No text parameter provided", status=400)

    firestore_client: google.cloud.firestore.Client = firestore.client()

    # Push the new message into Cloud Firestore using the Firebase Admin SDK.
    _, doc_ref = firestore_client.collection("messages").add({"original": original})

    # Send back a message that we've successfully written the message
    return https_fn.Response(f"Message with ID {doc_ref.id} added.")


@firestore_fn.on_document_created(document="messages/{pushId}")
def makeuppercase(event: firestore_fn.Event[firestore_fn.DocumentSnapshot | None]) -> None:
    """Listens for new documents to be added to /messages. If the document has
    an "original" field, creates an "uppercase" field containg the contents of
    "original" in upper case."""

    # Get the value of "original" if it exists.
    if event.data is None:
        return
    try:
        original = event.data.get("original")
    except KeyError:
        # No "original" field, so do nothing.
        return

    # Set the "uppercase" field.
    print(f"Uppercasing {event.params['pushId']}: {original}")
    upper = original.upper()
    event.data.reference.update({"uppercase": upper})

מידע על המדריך הזה

בחרנו בפונקציות שמופעלות על ידי Cloud Firestore ו-HTTP לדוגמה הזו, בין השאר כי אפשר לבדוק ביסודיות את הטריגרים האלה ברקע באמצעות Firebase Local Emulator Suite. ערכת הכלים הזו תומכת גם בטריגרים של Realtime Database,‏ Cloud Storage,‏ PubSub,‏ Auth ו-HTTP שניתנים להפעלה. אפשר לבדוק באופן אינטראקטיבי סוגים אחרים של טריגרים ברקע, כמו Remote Config וטריגרים של TestLab, באמצעות ערכות כלים שלא מתוארות בדף הזה.

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

יצירת פרויקט ב-Firebase

משתמשים חדשים ב-Firebase או ב-Cloud

אם אתם משתמשים חדשים ב-Firebase או ב-Google Cloud, אתם צריכים לפעול לפי השלבים הבאים.
אפשר גם לפעול לפי השלבים האלה כדי ליצור פרויקט Firebase חדש לגמרי (והפרויקט הבסיסי שלו ב-Google Cloud).

  1. נכנסים למסוף Firebase.
  2. לוחצים על הכפתור כדי ליצור פרויקט חדש ב-Firebase.
  3. בשדה הטקסט, מזינים שם לפרויקט.

    אם אתם חלק מארגון ב-Google Cloud, אתם יכולים לבחור באיזו תיקייה ליצור את הפרויקט.

  4. אם מוצגת בקשה, קוראים ומאשרים את התנאים של Firebase ולוחצים על Continue.
  5. (אופציונלי) מפעילים את העזרה מבוססת-AI במסוף Firebase (נקראת Gemini ב-Firebase), שיכולה לעזור לכם להתחיל ולייעל את תהליך הפיתוח.
  6. (אופציונלי) מגדירים את Google Analytics לפרויקט, כדי לאפשר חוויית שימוש אופטימלית במוצרי Firebase הבאים: Firebase A/B Testing,‏ Cloud Messaging,‏ Crashlytics,‏ In-App Messaging ו-Remote Config (כולל התאמה אישית).

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

  7. לוחצים על Create project.

‫Firebase יוצר את הפרויקט, מקצה כמה משאבים ראשוניים ומפעיל ממשקי API חשובים. בסיום התהליך, תועברו לדף הסקירה הכללית של פרויקט Firebase במסוף Firebase.

פרויקט קיים ב-Cloud

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

  1. נכנסים למסוף Firebase באמצעות החשבון שנותן גישה לפרויקט הקיים ב-Google Cloud.
  2. לוחצים על הכפתור כדי ליצור פרויקט חדש ב-Firebase.
  3. בתחתית הדף, לוחצים על Add Firebase to Google Cloud project.
  4. בשדה הטקסט, מתחילים להזין את שם הפרויקט הקיים ובוחרים את הפרויקט מהרשימה שמוצגת.
  5. לוחצים על פתיחת הפרויקט.
  6. אם מוצגת בקשה, קוראים ומאשרים את התנאים של Firebase ולוחצים על Continue.
  7. (אופציונלי) מפעילים את העזרה מבוססת-AI במסוף Firebase (נקראת Gemini ב-Firebase), שיכולה לעזור לכם להתחיל ולייעל את תהליך הפיתוח.
  8. (אופציונלי) מגדירים את Google Analytics לפרויקט, כדי לאפשר חוויית שימוש אופטימלית במוצרי Firebase הבאים: Firebase A/B Testing,‏ Cloud Messaging,‏ Crashlytics,‏ In-App Messaging ו-Remote Config (כולל התאמה אישית).

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

  9. לוחצים על הוספת Firebase.

‫Firebase מוסיף את Firebase לפרויקט הקיים. בסיום התהליך, תועברו לדף הסקירה הכללית של הפרויקט ב-Firebase במסוף Firebase.

הגדרת הסביבה ו-Firebase CLI

Node.js

כדי לכתוב פונקציות, צריך סביבת Node.js, וכדי לפרוס פונקציות בסביבת זמן הריצה של Cloud Functions, צריך את ה-CLI של Firebase. כדי להתקין את Node.js ו-npm, מומלץ להשתמש ב-Node Version Manager.

אחרי שמתקינים את Node.js ו-npm, מתקינים את ה-CLI של Firebase בשיטה שמעדיפים. כדי להתקין את ה-CLI באמצעות npm, משתמשים בפקודה:

npm install -g firebase-tools

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

Python

כדי לכתוב פונקציות, צריך סביבת Python, וכדי לפרוס פונקציות בסביבת זמן הריצה של Cloud Functions, צריך את ה-CLI של Firebase. מומלץ להשתמש ב-venv כדי לבודד יחסי תלות. יש תמיכה בגרסאות Python‏ 3.10 עד 3.13, וגרסה 3.13 היא סביבת זמן הריצה שמוגדרת כברירת מחדל.

אחרי שמתקינים את Python, מתקינים את ה-CLI של Firebase בשיטה שמעדיפים.

הפעלת הפרויקט

כשמאתחלים את ה-SDK של Firebase ל-Cloud Functions, נוצר פרויקט ריק שמכיל יחסי תלות וקוד לדוגמה מינימלי. אם אתם משתמשים ב-Node.js, אתם יכולים לבחור ב-TypeScript או ב-JavaScript כדי ליצור פונקציות. לצורך המדריך הזה, תצטרכו גם להפעיל את Cloud Firestore.

כדי להפעיל את הפרויקט:

  1. מריצים את firebase login כדי להתחבר דרך הדפדפן ולאמת את ה-CLI של Firebase.
  2. עוברים לספריית הפרויקט ב-Firebase.
  3. מריצים את firebase init firestore. במדריך הזה, אתם יכולים לאשר את ערכי ברירת המחדל כשמופיעה בקשה להגדיר את הכללים וקובצי האינדקס של Firestore. אם עדיין לא השתמשתם ב-Cloud Firestore בפרויקט הזה, תצטרכו גם לבחור מצב התחלה ומיקום ל-Firestore, כמו שמתואר במאמר תחילת השימוש ב-Cloud Firestore.
  4. מריצים את firebase init functions. ב-CLI תתבקשו לבחור בסיס קוד קיים או לאתחל בסיס קוד חדש ולתת לו שם. כשמתחילים, בסיס קוד אחד במיקום ברירת המחדל מספיק. בהמשך, ככל שההטמעה מתרחבת, יכול להיות שתרצו לארגן פונקציות בבסיסי קוד.
  5. ב-CLI יש את האפשרויות הבאות לתמיכה בשפה:

    • JavaScript
    • TypeScript
    • Python

    במדריך הזה, בוחרים באפשרות JavaScript או Python. כדי לכתוב ב-TypeScript, קראו את המאמר כתיבת פונקציות באמצעות TypeScript.

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

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

Node.js

myproject
+- .firebaserc    # Hidden file that helps you quickly switch between
|                 # projects with `firebase use`
|
+- firebase.json  # Describes properties for your project
|
+- functions/     # Directory containing all your functions code
      |
      +- .eslintrc.json  # Optional file containing rules for JavaScript linting.
      |
      +- package.json  # npm package file describing your Cloud Functions code
      |
      +- index.js      # Main source file for your Cloud Functions code
      |
      +- node_modules/ # Directory where your dependencies (declared in
                        # package.json) are installed

ב-Node.js, הקובץ package.json שנוצר במהלך האיניציאליזציה מכיל מפתח חשוב: "engines": {"node": "18"}. כאן מציינים את גרסת Node.js לכתיבה ולפריסה של פונקציות. אתם יכולים לבחור גרסאות נתמכות אחרות.

Python

myproject
+- .firebaserc    # Hidden file that helps you quickly switch between
|                 # projects with `firebase use`
|
+- firebase.json  # Describes properties for your project
|
+- functions/     # Directory containing all your functions code
      |
      +- main.py      # Main source file for your Cloud Functions code
      |
      +- requirements.txt  #  List of the project's modules and packages 
      |
      +- venv/ # Directory where your dependencies are installed

מייבאים את המודולים הנדרשים ומפעילים אפליקציה

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

Node.js

// The Cloud Functions for Firebase SDK to create Cloud Functions and triggers.
const {logger} = require("firebase-functions");
const {onRequest} = require("firebase-functions/https");
const {onDocumentCreated} = require("firebase-functions/firestore");

// The Firebase Admin SDK to access Firestore.
const {initializeApp} = require("firebase-admin/app");
const {getFirestore} = require("firebase-admin/firestore");

initializeApp();

Python

# The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
from firebase_functions import firestore_fn, https_fn

# The Firebase Admin SDK to access Cloud Firestore.
from firebase_admin import initialize_app, firestore
import google.cloud.firestore

app = initialize_app()

השורות האלה טוענות את המודולים הנדרשים ומאתחלות מופע של אפליקציית admin, שדרכו אפשר לבצע שינויים ב-Cloud Firestore. בכל מקום שבו יש תמיכה ב-Admin SDK, כמו ב-FCM, ב-Authentication וב-Firebase Realtime Database, הוא מספק דרך יעילה לשלב את Firebase באמצעות Cloud Functions.

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

הוספת הפונקציה "הוספת הודעה"

כדי להוסיף את הפונקציה "add message", מוסיפים את השורות הבאות לקובץ המקור:

Node.js

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addmessage = onRequest(async (req, res) => {
  // Grab the text parameter.
  const original = req.query.text;
  // Push the new message into Firestore using the Firebase Admin SDK.
  const writeResult = await getFirestore()
      .collection("messages")
      .add({original: original});
  // Send back a message that we've successfully written the message
  res.json({result: `Message with ID: ${writeResult.id} added.`});
});

Python

@https_fn.on_request()
def addmessage(req: https_fn.Request) -> https_fn.Response:
    """Take the text parameter passed to this HTTP endpoint and insert it into
    a new document in the messages collection."""
    # Grab the text parameter.
    original = req.args.get("text")
    if original is None:
        return https_fn.Response("No text parameter provided", status=400)

    firestore_client: google.cloud.firestore.Client = firestore.client()

    # Push the new message into Cloud Firestore using the Firebase Admin SDK.
    _, doc_ref = firestore_client.collection("messages").add({"original": original})

    # Send back a message that we've successfully written the message
    return https_fn.Response(f"Message with ID {doc_ref.id} added.")

הפונקציה "add message" היא נקודת קצה (endpoint) של HTTP. כל בקשה לנקודת הקצה גורמת להעברת אובייקטים של בקשה ותגובה ל-request handler של הפלטפורמה (onRequest() או on_request).

פונקציות HTTP הן סינכרוניות (בדומה לפונקציות שניתנות להפעלה), לכן צריך לשלוח תשובה כמה שיותר מהר ולדחות את העבודה באמצעות Cloud Firestore. הפונקציה "add message" של HTTP מעבירה ערך טקסט לנקודת הקצה של HTTP ומכניסה אותו למסד הנתונים בנתיב /messages/:documentId/original.

הוספת הפונקציה "הפיכה לאותיות רישיות"

כדי להשתמש בפונקציה "make uppercase", מוסיפים את השורות הבאות לקובץ המקור:

Node.js

// Listens for new messages added to /messages/:documentId/original
// and saves an uppercased version of the message
// to /messages/:documentId/uppercase
exports.makeuppercase = onDocumentCreated("/messages/{documentId}", (event) => {
  // Grab the current value of what was written to Firestore.
  const original = event.data.data().original;

  // Access the parameter `{documentId}` with `event.params`
  logger.log("Uppercasing", event.params.documentId, original);

  const uppercase = original.toUpperCase();

  // You must return a Promise when performing
  // asynchronous tasks inside a function
  // such as writing to Firestore.
  // Setting an 'uppercase' field in Firestore document returns a Promise.
  return event.data.ref.set({uppercase}, {merge: true});
});

Python

@firestore_fn.on_document_created(document="messages/{pushId}")
def makeuppercase(event: firestore_fn.Event[firestore_fn.DocumentSnapshot | None]) -> None:
    """Listens for new documents to be added to /messages. If the document has
    an "original" field, creates an "uppercase" field containg the contents of
    "original" in upper case."""

    # Get the value of "original" if it exists.
    if event.data is None:
        return
    try:
        original = event.data.get("original")
    except KeyError:
        # No "original" field, so do nothing.
        return

    # Set the "uppercase" field.
    print(f"Uppercasing {event.params['pushId']}: {original}")
    upper = original.upper()
    event.data.reference.update({"uppercase": upper})

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

סוגריים מסולסלים, למשל {documentId}, מקיפים "פרמטרים", תווים כלליים לחיפוש שחושפים את הנתונים התואמים שלהם בקריאה החוזרת (callback). ‫Cloud Firestore מפעיל את פונקציית ה-callback בכל פעם שמתווספות הודעות חדשות.

ב-Node.js, פונקציות מבוססות-אירועים כמו אירועי Cloud Firestore הן אסינכרוניות. פונקציית הקריאה החוזרת צריכה להחזיר null, אובייקט או Promise. אם לא מחזירים שום דבר, הפונקציה תגיע לזמן קצוב לתפוגה, תאותת על שגיאה ותנסה שוב. מידע נוסף זמין במאמר סנכרון, אסינכרוניות ו-Promises.

הדמיית ההפעלה של הפונקציות

Firebase Local Emulator Suite מאפשר לכם לפתח ולבדוק אפליקציות במחשב המקומי במקום לפרוס אותן בפרויקט Firebase. מומלץ מאוד לבצע בדיקות מקומיות במהלך הפיתוח, בין השאר כי הן מפחיתות את הסיכון לשגיאות בקוד שעלולות לגרום לעלויות בסביבת הייצור (לדוגמה, לולאה אינסופית).

כדי לדמות את הפונקציות:

  1. מריצים את firebase emulators:start ובודקים את הפלט של כתובת ה-URL של Emulator Suite UI. כברירת מחדל, הכתובת היא localhost:4000, אבל יכול להיות שהיא מתארחת ביציאה אחרת במחשב. מזינים את כתובת ה-URL הזו בדפדפן כדי לפתוח את Emulator Suite UI.

  2. בודקים את הפלט של הפקודה firebase emulators:start כדי למצוא את כתובת ה-URL של פונקציית ה-HTTP. הוא ייראה דומה ל-http://localhost:5001/MY_PROJECT/us-central1/addMessage, אבל:

    1. ‫MY_PROJECT יוחלף במזהה הפרויקט שלכם.
    2. יכול להיות שהיציאה במחשב המקומי שלכם שונה.
  3. מוסיפים את מחרוזת השאילתה ?text=uppercaseme לסוף כתובת ה-URL של הפונקציה. הוא אמור להיראות כך: http://localhost:5001/MY_PROJECT/us-central1/addMessage?text=uppercaseme. אפשר לשנות את ההודעה "uppercaseme" להודעה בהתאמה אישית.

  4. כדי ליצור הודעה חדשה, פותחים את כתובת ה-URL בכרטיסייה חדשה בדפדפן.

  5. כדי לראות את ההשפעות של הפונקציות ב-Emulator Suite UI:

    1. בכרטיסייה Logs אמורים להופיע יומנים חדשים שמציינים שפונקציות ה-HTTP פעלו בהצלחה:

      i functions: Beginning execution of "addMessage"

      i functions: Beginning execution of "makeUppercase"

    2. בכרטיסייה Firestore אמור להופיע מסמך שמכיל את ההודעה המקורית ואת הגרסה של ההודעה באותיות רישיות (אם במקור היא הייתה "uppercaseme", תראו "UPPERCASEME").

פריסת פונקציות בסביבת ייצור

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

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

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

     firebase deploy --only functions
     

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

    Function URL (addMessage): https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage
    

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

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

  2. משתמשים בכתובת ה-URL שנוצרה על ידי ה-CLI, מוסיפים פרמטר של שאילתת טקסט ופותחים אותה בדפדפן:

    https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage?text=uppercasemetoo
    

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

אחרי שפורסים ומריצים פונקציות, אפשר לראות את היומנים במסוף Google Cloud. אם אתם צריכים למחוק פונקציות בפיתוח או בסביבת הייצור, השתמשו ב-CLI של Firebase.

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

השלבים הבאים

במסמכי התיעוד האלה מוסבר איך לנהל פונקציות ב-Cloud Functions ואיך לטפל בכל סוגי האירועים שנתמכים ב-Cloud Functions.

כדי לקבל מידע נוסף על Cloud Functions, אפשר גם: