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

כדי להתחיל להשתמש ב-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 ואז לוחצים על המשך.
  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. לוחצים על יצירת פרויקט.

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

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

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

  1. נכנסים אל מסוף Firebase באמצעות החשבון שדרכו יש לכם גישה לפרויקט Google Cloud הקיים.
  2. לוחצים על הלחצן כדי ליצור פרויקט חדש ב-Firebase.
  3. בתחתית הדף, לוחצים על הוספת Firebase לפרויקט בענן של Google Cloud.
  4. בשדה הטקסט, מתחילים להזין את שם הפרויקט של הפרויקט הקיים, ואז בוחרים את הפרויקט מהרשימה שמוצגת.
  5. לוחצים על פתיחת פרויקט.
  6. אם מופיעה בקשה, קוראים ומאשרים את התנאים של Firebase ואז לוחצים על המשך.
  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, תצטרכו את Firebase CLI. מומלץ להשתמש ב-מנהל גרסאות של Node כדי להתקין את Node.js ואת npm.

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

npm install -g firebase-tools

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

Python

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

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

אתחול הפרויקט

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

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

  1. מריצים את הפקודה firebase login כדי להיכנס דרך הדפדפן ולאמת את Firebase CLI.
  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.

ממשק Firebase CLI מתקין באופן אוטומטי את SDK של Firebase לאדמינים ואת מודולי Firebase SDK for 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. כל בקשה לנקודת הקצה גורמת להעברת אובייקטים של בקשה ותגובה אל handler הבקשות של הפלטפורמה (onRequest() או on_request).

פונקציות HTTP הן סינכרוניות (בדומה לפונקציות שאפשר להפעיל), ולכן צריך לשלוח תגובה במהירות האפשרית ולדחות עבודה באמצעות Cloud Firestore. הפונקציה HTTP ‏'add message' מעבירה ערך טקסט לנקודת הקצה של 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} – מקיפים 'פרמטרים', תווים כלליים שחושפים את הנתונים התואמים שלהם בקריאה החוזרת. ‫Cloud Firestore מפעיל את הקריאה החוזרת בכל פעם שמוסיפים הודעות חדשות.

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

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

הפקודה 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, אפשר גם: