כדי להתחיל להשתמש ב-Cloud Functions, כדאי לעיין במדריך הזה. המדריך מתחיל במשימות ההגדרה הנדרשות ועובר יצירה, בדיקה ופריסה של שתי פונקציות קשורות:
- פונקציית add message שחשפה כתובת URL שמקבלת ערך טקסט ומשמרת אותו ב-Cloud Firestore.
- פונקציית 'make uppercase' שמופעל בכתיבה של 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/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/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 callable. אפשר לבדוק באופן אינטראקטיבי סוגים אחרים של טריגרים ברקע, כמו טריגרים של Remote Config ו-TestLab, באמצעות ערכות כלים שלא מתוארות בדף הזה.
בחלקים הבאים של המדריך מוסבר בפירוט איך יוצרים, בודקים ופורסים את הדוגמה.
יצירת פרויקט Firebase
-
במסוף Firebase, לוחצים על Add project.
-
כדי להוסיף משאבים של Firebase לפרויקט Google Cloud קיים, מזינים את שם הפרויקט או בוחרים אותו בתפריט הנפתח.
-
כדי ליצור פרויקט חדש, מזינים את שם הפרויקט הרצוי. אפשר גם לערוך את מזהה הפרויקט שמוצג מתחת לשם הפרויקט.
-
-
אם תופיע בקשה, קוראים את התנאים של Firebase ומאשרים אותם.
-
לוחצים על המשך.
-
(אופציונלי) מגדירים את Google Analytics בפרויקט. כך תוכלו ליהנות מחוויה אופטימלית בכל אחד מהמוצרים הבאים של Firebase:
בוחרים חשבון Google Analytics קיים או יוצרים חשבון חדש.
אם יוצרים חשבון חדש, צריך לבחור את המיקום המדווח Analytics ואז לאשר את הגדרות שיתוף הנתונים ואת התנאים Google Analytics שרלוונטיים לפרויקט שלך.
-
לוחצים על Create project (או על Add Firebase, אם משתמשים בפרויקט Google Cloud קיים).
מערכת Firebase מקצה משאבים באופן אוטומטי לפרויקט Firebase. בסיום התהליך, תועברו לדף הסקירה הכללית של הפרויקט ב-Firebase במסוף Firebase.
הגדרת הסביבה ו-Firebase CLI
Node.js
כדי לכתוב פונקציות צריך סביבת Node.js, וכדי לפרוס פונקציות בסביבת זמן הריצה של Cloud Functions צריך את ה-CLI Firebase. מומלץ להשתמש ב-Node Version Manager כדי להתקין את Node.js ו-npm.
אחרי שמתקינים את 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.11.
אחרי שמתקינים את Python, מתקינים את ה-CLI של Firebase באמצעות השיטה המועדפת עליכם.
הפעלת הפרויקט
כשמפעילים את Firebase SDK עבור Cloud Functions, נוצר פרויקט ריק שמכיל יחסי תלות וקוד לדוגמה מינימלי. אם אתם משתמשים ב-Node.js, תוכלו לבחור ב-TypeScript או ב-JavaScript כדי ליצור פונקציות. לצורך המדריך הזה, תצטרכו גם לאתחל את Cloud Firestore.
כדי לאתחל את הפרויקט:
- מריצים את
firebase login
כדי להתחבר דרך הדפדפן ולאמת את ה-CLI של Firebase. - עוברים לספרייה של פרויקט Firebase.
- מריצים את
firebase init firestore
. במדריך הזה, אפשר לאשר את ערכי ברירת המחדל כשמתבקשים להזין כללים וקובצי אינדקס של Firestore. אם עדיין לא השתמשתם ב-Cloud Firestore בפרויקט הזה, תצטרכו גם לבחור מצב התחלה ומיקום ל-Firestore, כפי שמתואר במאמר תחילת העבודה עם Cloud Firestore. - מריצים את
firebase init functions
. ב-CLI תתבקשו לבחור בסיס קוד קיים או לאתחל בסיס קוד חדש ולתת לו שם. כשרק מתחילים, מספיק בסיס קוד אחד במיקום ברירת המחדל. בהמשך, ככל שההטמעה תתרחב, כדאי לארגן את הפונקציות בבסיס קוד. ב-CLI יש את האפשרויות הבאות לקבלת תמיכה בשפה:
- JavaScript
- TypeScript
- Python
למדריך הזה, בוחרים JavaScript או Python. למידע נוסף על כתיבת קוד ב-TypeScript, ראו כתיבת פונקציות ב-TypeScript.
ב-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 ו-Admin 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/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/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 Admin ואת ה-SDK של Firebase למודולים של Cloud Functions כשמאתחלים את הפרויקט. למידע נוסף על הוספת ספריות של צד שלישי לפרויקט, ראו תלות בטיפול.
הוספת הפונקציה add message
בפונקציה 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. כל בקשה לנקודת הקצה מובילה ליצירת אובייקטים של בקשה ותגובה, שמועברים לטיפול בבקשות בפלטפורמה (onRequest()
או on_request
).
פונקציות HTTP הן סינכרוניות (בדומה לפונקציות ניתנות לקריאה), לכן צריך לשלוח תשובה מהר ככל האפשר ולדחות את העבודה באמצעות Cloud Firestore. פונקציית ה-HTTP 'add message' מעבירה ערך טקסט לנקודת הקצה של ה-HTTP ומוסיפה אותו למסד הנתונים בנתיב /messages/:documentId/original
.
מוסיפים את הפונקציה 'make uppercase'
כדי להשתמש בפונקציה 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.
אם לא תחזירו דבר, יפוג הזמן הקצוב לפונקציה, תופיע הודעה על שגיאה ותתבצע ניסיון חוזר. Sync, Async ו-Promises
הדמיה של הפעלת הפונקציות
באמצעות Firebase Local Emulator Suite אפשר ליצור ולבדוק אפליקציות במחשב המקומי במקום לפרוס אותן בפרויקט Firebase. מומלץ מאוד לבצע בדיקה מקומית במהלך הפיתוח, בין היתר כי היא מפחיתה את הסיכון לשגיאות תכנות שעלולות לגרום לעלויות בסביבת הייצור (לדוגמה, לולאה אינסופית).
כדי לדמות את הפונקציות:
מריצים את
firebase emulators:start
ובודקים את הפלט כדי למצוא את כתובת ה-URL של ה-Emulator Suite UI. ברירת המחדל היא localhost:4000, אבל יכול להיות שהיא תתארח ביציאה אחרת במחשב. מזינים את כתובת ה-URL הזו בדפדפן כדי לפתוח את Emulator Suite UI.בודקים את הפלט של הפקודה
firebase emulators:start
לכתובת ה-URL של פונקציית ה-HTTP. הוא ייראה דומה ל-http://localhost:5001/MY_PROJECT/us-central1/addMessage
, מלבד:- הערך
MY_PROJECT
יוחלף במזהה הפרויקט. - יכול להיות שהיציאה תהיה שונה במחשב המקומי.
- הערך
מוסיפים את מחרוזת השאילתה
?text=uppercaseme
לסוף כתובת ה-URL של הפונקציה. הוא אמור להיראות כך:http://localhost:5001/MY_PROJECT/us-central1/addMessage?text=uppercaseme
. אפשר גם לשנות את ההודעה "uppercaseme" (אות גדולה) להודעה מותאמת אישית.כדי ליצור הודעה חדשה, פותחים את כתובת ה-URL בכרטיסייה חדשה בדפדפן.
אפשר לראות את ההשפעות של הפונקציות ב-Emulator Suite UI:
בכרטיסייה Logs אמורים להופיע יומנים חדשים שמציינים שפונקציות ה-HTTP פועלות בהצלחה:
i functions: Beginning execution of "addMessage"
i functions: Beginning execution of "makeUppercase"
בכרטיסייה Firestore אמור להופיע מסמך שמכיל את ההודעה המקורית וגם את הגרסה של ההודעה עם אותיות רישיות (אם ההודעה המקורית הייתה 'uppercaseme', תוצג 'UPPERCASEME').
פריסת פונקציות בסביבת הייצור
אחרי שהפונקציות יפעלו כצפוי במהדורת הסימולציה, תוכלו לפרוס, לבדוק ולהריץ אותן בסביבת הייצור. חשוב לזכור שכדי לפרוס את הפרויקט בסביבת הייצור הוא חייב להיות בתוכנית התמחור והתשלומים של Bllaze. מחירון Cloud Functions
כדי להשלים את המדריך, תצטרכו לפרוס את הפונקציות ולאחר מכן להריץ אותן.
מריצים את הפקודה הבאה כדי לפרוס את הפונקציות:
firebase deploy --only functions
אחרי הרצת הפקודה הזו, ה-CLI של Firebase יפיק את כתובת ה-URL של כל נקודות הקצה של פונקציות ה-HTTP. במסוף אמורה להופיע שורה כזו:
Function URL (addMessage): https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage
כתובת ה-URL מכילה את מזהה הפרויקט ואת האזור של פונקציית ה-HTTP. אין צורך לדאוג עכשיו, אבל בחלק מפונקציות ה-HTTP בסביבת הייצור צריך לציין מיקום כדי למזער את זמן האחזור של הרשת.
אם נתקלתם בשגיאות גישה כמו 'לא ניתן להעניק הרשאת גישה לפרויקט', נסו לבדוק את הכינוי של הפרויקט.
באמצעות הפלט של כתובת ה-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 בדרכים הבאות:
- תרחישי שימוש ל-Cloud Functions
- כדאי לנסות את Cloud Functions Codelab.
- בודקים ומריצים דוגמאות קוד ב-GitHub