1. סקירה כללית
ב-codelab הזה תלמדו איך להשתמש ב-Cloud Functions for Firebase כדי להוסיף פונקציונליות לאפליקציית צ'אט באינטרנט על ידי שליחת התראות למשתמשים באפליקציית הצ'אט.
מה תלמדו
- יוצרים פונקציות ב-Google Cloud באמצעות Firebase SDK.
- הפעלת Cloud Functions על סמך אירועים של Auth, Cloud Storage ו-Cloud Firestore.
- מוסיפים תמיכה ב-Firebase Cloud Messaging לאפליקציית האינטרנט.
מה צריך להכין
- כרטיס אשראי. כדי להשתמש ב-Cloud Functions for Firebase, צריך להירשם לתוכנית Blaze ב-Firebase. המשמעות היא שתצטרכו להפעיל את החיוב בפרויקט Firebase באמצעות כרטיס אשראי.
- סביבת פיתוח משולבת (IDE) או עורך טקסט לפי בחירתכם, כמו WebStorm, Atom או Sublime.
- טרמינל להרצת פקודות של מעטפת עם NodeJS v9 מותקן.
- דפדפן כמו Chrome.
- קוד לדוגמה. הסבר על כך מופיע בשלב הבא.
2. קבלת קוד לדוגמה
משכפלים את המאגר ב-GitHub משורת הפקודה:
git clone https://github.com/firebase/friendlychat
ייבוא של אפליקציה למתחילים
בסביבת הפיתוח המשולבת (IDE), פותחים או מייבאים את הספרייה cloud-functions-start
מספריית הקוד לדוגמה. בספרייה הזו יש קוד התחלתי ל-codelab, שכולל אפליקציית אינטרנט של Chat עם פונקציונליות מלאה.
3. יצירת פרויקט Firebase והגדרת האפליקציה
יצירת פרויקט
- נכנסים למסוף Firebase באמצעות חשבון Google.
- לוחצים על הלחצן כדי ליצור פרויקט חדש, ואז מזינים שם לפרויקט (לדוגמה,
FriendlyChat
).
- לוחצים על המשך.
- אם מוצגת בקשה לעשות זאת, קוראים ומאשרים את התנאים של Firebase, ואז לוחצים על המשך.
- (אופציונלי) מפעילים את העזרה מבוססת-AI במסוף Firebase (שנקראת Gemini ב-Firebase).
- ב-codelab הזה לא צריך להשתמש ב-Google Analytics, ולכן משביתים את האפשרות Google Analytics.
- לוחצים על יצירת פרויקט, מחכים שהפרויקט יוקצה ולוחצים על המשך.
שדרוג לתוכנית Blaze
כדי להשתמש ב-Cloud Functions for Firebase וב-Cloud Storage for Firebase, הפרויקט שלכם ב-Firebase צריך להיות בתוכנית התמחור 'תשלום לפי שימוש' (Blaze), כלומר הוא צריך להיות מקושר לחשבון לחיוב ב-Cloud.
- בחשבון לחיוב ב-Cloud צריך להגדיר אמצעי תשלום, כמו כרטיס אשראי.
- אם אתם חדשים ב-Firebase וב-Google Cloud, כדאי לבדוק אם אתם עומדים בדרישות לקבלת קרדיט בסך 300$וחשבון לחיוב ב-Cloud עם תקופת ניסיון בחינם.
- אם אתם משתתפים בסדנת קוד כחלק מאירוע, כדאי לשאול את מארגן האירוע אם יש קרדיטים ל-Cloud.
אם אין לכם גישה לכרטיס אשראי או שאתם לא רוצים להמשיך עם תוכנית התמחור Blaze, אתם יכולים להשתמש בחבילת כלי האמולציה של Firebase, שתאפשר לכם לבצע אמולציה של Cloud Functions בחינם במחשב המקומי.
לכל הפרויקטים ב-Firebase, כולל אלה שרשומים לתוכנית התמחור Blaze, עדיין יש גישה למכסות שימוש ללא עלות ב-Cloud Functions. השלבים שמפורטים ב-codelab הזה יהיו במסגרת מגבלות השימוש של תוכנית בחינם. עם זאת, יופיעו חיובים קטנים (בסביבות 0.03 $) מ-Cloud Storage, שמשמש לאירוח תמונות ה-build של Cloud Functions.
כדי לשדרג את הפרויקט לתוכנית Blaze, פועלים לפי השלבים הבאים:
- במסוף Firebase, בוחרים באפשרות שדרוג התוכנית.
- בוחרים בתוכנית Blaze. פועלים לפי ההוראות במסך כדי לקשר חשבון לחיוב ב-Cloud לפרויקט.
אם הייתם צריכים ליצור חשבון לחיוב ב-Cloud כחלק מהשדרוג, יכול להיות שתצטרכו לחזור לתהליך השדרוג במסוף Firebase כדי להשלים את השדרוג.
הפעלת אימות Google
כדי לאפשר למשתמשים להיכנס לאפליקציה, נשתמש באימות של Google, שצריך להיות מופעל.
במסוף Firebase, פותחים את הקטע Build (פיתוח) > Authentication (אימות) > הכרטיסייה Sign-in method (שיטת כניסה) (או לוחצים כאן כדי לעבור אליה). לאחר מכן, מפעילים את ספק הכניסה Google ולוחצים על שמירה. כך המשתמשים יוכלו להיכנס לאפליקציית האינטרנט באמצעות חשבונות Google שלהם.
בנוסף, אפשר להגדיר את השם הגלוי לכל של האפליקציה כ-Friendly Chat:
הגדרת Cloud Storage for Firebase
האפליקציה משתמשת ב-Cloud Storage כדי להעלות תמונות.
כך מגדירים את Cloud Storage for Firebase בפרויקט Firebase:
- בחלונית הימנית במסוף Firebase, מרחיבים את Build (פיתוח) ובוחרים באפשרות Storage (אחסון).
- לוחצים על תחילת העבודה.
- בוחרים מיקום לקטגוריית האחסון שמוגדרת כברירת מחדל.
קטגוריות ב-US-WEST1
, ב-US-CENTRAL1
וב-US-EAST1
יכולות ליהנות מהמסלול תמיד בחינם של Google Cloud Storage. התמחור והשימוש בקטגוריות בכל המיקומים האחרים מפורטים בתמחור ובשימוש ב-Google Cloud Storage. - לוחצים על התחלה במצב בדיקה. חשוב לקרוא את כתב הוויתור בנוגע לכללי האבטחה.
אין להפיץ או לחשוף אפליקציה לציבור בלי להוסיף כללי אבטחה לדלי האחסון. - לוחצים על יצירה.
הוספת אפליקציית אינטרנט
במסוף Firebase, מוסיפים אפליקציית אינטרנט. כדי לעשות זאת, עוברים אל Project Settings (הגדרות הפרויקט) וגוללים למטה אל Add app (הוספת אפליקציה). בוחרים באפשרות 'אינטרנט' כפלטפורמה, מסמנים את התיבה להגדרת Firebase Hosting, רושמים את האפליקציה ולוחצים על Next (הבא) כדי להשלים את שאר השלבים. בסיום, לוחצים על Continue to console (המשך למסוף).
4. התקנה של ממשק שורת הפקודה של Firebase
ממשק שורת הפקודה (CLI) של Firebase מאפשר להפעיל את אפליקציית האינטרנט באופן מקומי ולפרוס את אפליקציית האינטרנט ואת Cloud Functions.
כדי להתקין או לשדרג את ה-CLI, מריצים את פקודת ה-npm הבאה:
npm -g install firebase-tools
כדי לוודא שה-CLI הותקן בצורה נכונה, פותחים מסוף ומריצים את הפקודה:
firebase --version
מוודאים שגרסת Firebase CLI היא מעל 4.0.0, כדי שיהיו בה כל התכונות העדכניות שנדרשות ל-Cloud Functions. אם לא, מריצים את הפקודה npm install -g firebase-tools
כדי לשדרג כמו שמוסבר למעלה.
כדי לתת הרשאה ל-Firebase CLI מריצים את הפקודה:
firebase login
מוודאים שאתם בספרייה cloud-functions-start
, ואז מגדירים את Firebase CLI לשימוש בפרויקט Firebase:
firebase use --add
לאחר מכן בוחרים את מזהה הפרויקט ופועלים לפי ההוראות. כשמופיעה בקשה לכך, אפשר לבחור כינוי כלשהו, כמו codelab
.
5. פריסה והפעלה של אפליקציית האינטרנט
אחרי שייבאתם והגדרתם את הפרויקט, אתם מוכנים להפעיל את אפליקציית האינטרנט בפעם הראשונה. פותחים חלון טרמינל, עוברים לתיקייה cloud-functions-start
ומפעילים את אפליקציית האינטרנט ב-Firebase Hosting באמצעות הפקודה:
firebase deploy --except functions
זה הפלט שיוצג במסוף:
i deploying database, storage, hosting
✔ database: rules ready to deploy.
i storage: checking rules for compilation errors...
✔ storage: rules file compiled successfully
i hosting: preparing ./ directory for upload...
✔ hosting: ./ folder uploaded successfully
✔ storage: rules file compiled successfully
✔ hosting: 8 files uploaded successfully
i starting release process (may take several minutes)...
✔ Deploy complete!
Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview
Hosting URL: https://friendlychat-1234.firebaseapp.com
פתיחת אפליקציית האינטרנט
בשורה האחרונה צריכה להופיע כתובת ה-URL של האחסון. עכשיו אפליקציית האינטרנט אמורה להיות זמינה מכתובת ה-URL הזו, שצריכה להיות בפורמט https://<project-id>.firebaseapp.com. פותחים אותה. אמור להופיע ממשק משתמש של אפליקציית Chat.
נכנסים לאפליקציה באמצעות הלחצן כניסה באמצעות חשבון Google ומוסיפים הודעות ותמונות:
אם נכנסים לאפליקציה בפעם הראשונה בדפדפן חדש, צריך לאשר את ההתראות כשמופיעה בקשה לכך:
בהמשך נצטרך להפעיל את ההתראות.
אם לחצתם בטעות על חסימה, תוכלו לשנות את ההגדרה הזו. לשם כך, לוחצים על הלחצן 🔒 מאובטח בצד ימין של כתובת ה-URL בסרגל הכתובות של Chrome, ומעבירים את הסרגל שליד התראות למצב פעיל:
עכשיו נוסיף פונקציונליות באמצעות Firebase SDK ל-Cloud Functions.
6. מדריך הפונקציות
Cloud Functions מאפשר לכם להריץ קוד בענן בקלות, בלי שתצטרכו להגדיר שרת. במאמר הזה נסביר איך ליצור פונקציות שמגיבות לאירועים במסד הנתונים של Firebase Auth, Cloud Storage ו-Firebase Firestore. נתחיל עם Auth.
כשמשתמשים ב-Firebase SDK for Cloud Functions, קוד הפונקציות נמצא בספרייה functions
(כברירת מחדל). קוד הפונקציות שלכם הוא גם אפליקציית Node.js, ולכן הוא צריך package.json
שמספק מידע על האפליקציה ומפרט את התלות שלה.
כדי להקל עליך, כבר יצרנו את הקובץ functions/index.js
שבו הקוד שלך יופיע. מומלץ לבדוק את הקובץ הזה לפני שממשיכים.
cd functions
ls
אם אתם לא מכירים את Node.js, כדאי לקרוא עליה לפני שתמשיכו ב-codelab.
בקבצים package.json
כבר מופיעות שתי תלויות נדרשות: Firebase SDK for Cloud Functions ו-Firebase Admin SDK. כדי להתקין אותם באופן מקומי, עוברים לתיקייה functions
ומריצים את הפקודה:
npm install
עכשיו נסתכל על הקובץ index.js
:
index.js
/**
* Copyright 2017 Google Inc. All Rights Reserved.
* ...
*/
// TODO(DEVELOPER): Import the Cloud Functions for Firebase and the Firebase Admin modules here.
// TODO(DEVELOPER): Write the addWelcomeMessage Function here.
// TODO(DEVELOPER): Write the blurImages Function here.
// TODO(DEVELOPER): Write the sendNotification Function here.
אנחנו מייבאים את המודולים הנדרשים ואז כותבים שלוש פונקציות במקום ה-TODO. נתחיל בייבוא של מודולי Node הנדרשים.
7. ייבוא המודולים Cloud Functions ו-Firebase Admin
במהלך ה-codelab הזה נשתמש בשני מודולים: firebase-functions
מאפשר לכתוב טריגרים ויומנים של Cloud Functions, ו-firebase-admin
מאפשר להשתמש בפלטפורמת Firebase בשרת עם גישת אדמין כדי לבצע פעולות כמו כתיבה ל-Cloud Firestore או שליחת התראות FCM.
בקובץ index.js
, מחליפים את TODO
הראשון בטקסט הבא:
index.js
/**
* Copyright 2017 Google Inc. All Rights Reserved.
* ...
*/
// Import the Firebase SDK for Google Cloud Functions.
const functions = require('firebase-functions');
// Import and initialize the Firebase Admin SDK.
const admin = require('firebase-admin');
admin.initializeApp();
// TODO(DEVELOPER): Write the addWelcomeMessage Function here.
// TODO(DEVELOPER): Write the blurImages Function here.
// TODO(DEVELOPER): Write the sendNotification Function here.
אפשר להגדיר את Firebase Admin SDK באופן אוטומטי כשפורסים אותו בסביבת Cloud Functions או במאגרי נתונים אחרים של Google Cloud Platform. זה קורה כשמפעילים את admin.initializeApp()
בלי ארגומנטים.
עכשיו נוסיף פונקציה שפועלת כשמשתמש נכנס בפעם הראשונה לאפליקציית הצ'אט, ונוסיף הודעת צ'אט כדי לברך את המשתמש.
8. קבלת פנים למשתמשים חדשים
מבנה ההודעות ב-Chat
ההודעות שמתפרסמות בפיד הצ'אט של FriendlyChat מאוחסנות ב-Cloud Firestore. כדאי לעיין במבנה הנתונים שבו אנחנו משתמשים להודעה. כדי לעשות את זה, שולחים הודעה חדשה בצ'אט עם הכיתוב Hello World:
התוצאה צריכה להיות:
במסוף Firebase, לוחצים על Firestore Database (מסד נתונים של Firestore) בקטע Build (פיתוח). אוסף ההודעות ומסמך אחד שמכיל את ההודעה שכתבתם אמורים להופיע:
כפי שאפשר לראות, הודעות בצ'אט מאוחסנות ב-Cloud Firestore כמסמך עם המאפיינים name
, profilePicUrl
, text
ו-timestamp
שנוספו לאוסף messages
.
הוספת הודעות פתיחה
הפונקציה הראשונה של Cloud מוסיפה הודעה שמקבלת בברכה משתמשים חדשים לשיחה. לשם כך, אפשר להשתמש בטריגר functions.auth().onCreate
, שמפעיל את הפונקציה בכל פעם שמשתמש נכנס לאפליקציית Firebase בפעם הראשונה. מוסיפים את הפונקציה addWelcomeMessages
לקובץ index.js
:
index.js
// Adds a message that welcomes new users into the chat.
exports.addWelcomeMessages = functions.auth.user().onCreate(async (user) => {
functions.logger.log('A new user signed in for the first time.');
const fullName = user.displayName || 'Anonymous';
// Saves the new welcome message into the database
// which then displays it in the FriendlyChat clients.
await admin.firestore().collection('messages').add({
name: 'Firebase Bot',
profilePicUrl: '/images/firebase-logo.png', // Firebase logo
text: `${fullName} signed in for the first time! Welcome!`,
timestamp: admin.firestore.FieldValue.serverTimestamp(),
});
functions.logger.log('Welcome message written to database.');
});
הוספת הפונקציה לאובייקט המיוחד exports
היא הדרך של Node להפוך את הפונקציה לנגישה מחוץ לקובץ הנוכחי, והיא נדרשת ל-Cloud Functions.
בפונקציה שלמעלה, אנחנו מוסיפים לרשימת הודעות הצ'אט הודעת פתיחה חדשה שפורסמה על ידי Firebase Bot. אנחנו עושים את זה באמצעות השיטה add
באוסף messages
ב-Cloud Firestore, שבו מאוחסנות ההודעות בצ'אט.
מכיוון שמדובר בפעולה אסינכרונית, צריך להחזיר את Promise כדי לציין מתי Cloud Firestore סיים את הכתיבה, כך ש-Cloud Functions לא יופעל מוקדם מדי.
פריסת Cloud Functions
פונקציות של Cloud Functions יהיו פעילות רק אחרי שתפרסו אותן. כדי לעשות זאת, מריצים את הפקודה הבאה בשורת הפקודה:
firebase deploy --only functions
זה הפלט שיוצג במסוף:
i deploying functions
i functions: ensuring necessary APIs are enabled...
⚠ functions: missing necessary APIs. Enabling now...
i env: ensuring necessary APIs are enabled...
⚠ env: missing necessary APIs. Enabling now...
i functions: waiting for APIs to activate...
i env: waiting for APIs to activate...
✔ env: all necessary APIs are enabled
✔ functions: all necessary APIs are enabled
i functions: preparing functions directory for uploading...
i functions: packaged functions (X.XX KB) for uploading
✔ functions: functions folder uploaded successfully
i starting release process (may take several minutes)...
i functions: creating function addWelcomeMessages...
✔ functions[addWelcomeMessages]: Successful create operation.
✔ functions: all functions deployed successfully!
✔ Deploy complete!
Project Console: https://console.firebase.google.com/project/friendlypchat-1234/overview
בדיקת הפונקציה
אחרי שהפונקציה נפרסת בהצלחה, צריך שיהיה משתמש שייכנס לחשבון בפעם הראשונה.
- פותחים את האפליקציה בדפדפן באמצעות כתובת ה-URL של האירוח (בפורמט
https://<project-id>.firebaseapp.com
). - משתמש חדש צריך להיכנס לאפליקציה בפעם הראשונה באמצעות הלחצן כניסה.
- אם כבר נכנסתם לאפליקציה, אתם יכולים לפתוח את Firebase Console Authentication ולמחוק את החשבון שלכם מרשימת המשתמשים. אחר כך נכנסים שוב לחשבון.
- אחרי שתיכנסו לחשבון, אמורה להופיע באופן אוטומטי הודעת פתיחה:
9. ניהול תמונות
המשתמשים יכולים להעלות כל סוג של תמונה בצ'אט, ותמיד חשוב לבצע מודרציה של תמונות פוגעניות, במיוחד בפלטפורמות חברתיות ציבוריות. ב-FriendlyChat, התמונות שמתפרסמות בצ'אט מאוחסנות בקטגוריות של Cloud Storage.
באמצעות Cloud Functions, אפשר לזהות העלאות חדשות של תמונות באמצעות הטריגר functions.storage().onFinalize
. הפונקציה הזו תפעל בכל פעם שקובץ חדש יועלה או ישונה ב-Cloud Storage.
כדי לבדוק תמונות, אנחנו מבצעים את התהליך הבא:
- בודקים אם התמונה מסומנת כתוכן למבוגרים או כתוכן אלים באמצעות Cloud Vision API.
- אם התמונה סומנה, מורידים אותה במופע הפעיל של Functions.
- מטשטשים את התמונה באמצעות ImageMagick.
- מעלים את התמונה המטושטשת ל-Cloud Storage.
הפעלת Cloud Vision API
מכיוון שנשתמש ב-Google Cloud Vision API בפונקציה הזו, צריך להפעיל את ה-API בפרויקט Firebase. עוברים אל הקישור הזה, בוחרים את פרויקט Firebase ומפעילים את ה-API:
התקנת יחסי תלות
כדי לבצע צנזורה של תמונות, נשתמש בספריית הלקוח של Google Cloud Vision ל-Node.js, @google-cloud/vision, כדי להריץ תמונות דרך Cloud Vision API ולזהות תמונות לא הולמות.
כדי להתקין את החבילה הזו באפליקציית Cloud Functions, מריצים את הפקודה הבאה של npm install --save
. חשוב לוודא שאתם נמצאים בספרייה functions
.
npm install --save @google-cloud/vision@2.4.0
החבילה תותקן באופן מקומי ותתווסף כהצהרת תלות בקובץ package.json
.
ייבוא והגדרה של פריטים בקשרי תלות
כדי לייבא את התלויות שהותקנו וכמה מודולים מרכזיים של Node.js (path
, os
ו-fs
) שנצטרך בקטע הזה, מוסיפים את השורות הבאות לחלק העליון של הקובץ index.js
:
index.js
const Vision = require('@google-cloud/vision');
const vision = new Vision.ImageAnnotatorClient();
const {promisify} = require('util');
const exec = promisify(require('child_process').exec);
const path = require('path');
const os = require('os');
const fs = require('fs');
הפונקציה תפעל בסביבת Google Cloud, ולכן אין צורך להגדיר את הספריות Cloud Storage ו-Cloud Vision: הן יוגדרו אוטומטית לשימוש בפרויקט שלכם.
זיהוי תמונות בלתי הולמות
תשתמשו בטריגר של functions.storage.onChange
Cloud Functions, שמריץ את הקוד ברגע שנוצר או משתנה קובץ או תיקייה בקטגוריה של Cloud Storage. מוסיפים את הפונקציה blurOffensiveImages
לקובץ index.js
:
index.js
// Checks if uploaded images are flagged as Adult or Violence and if so blurs them.
exports.blurOffensiveImages = functions.runWith({memory: '2GB'}).storage.object().onFinalize(
async (object) => {
const imageUri = `gs://${object.bucket}/${object.name}`;
// Check the image content using the Cloud Vision API.
const batchAnnotateImagesResponse = await vision.safeSearchDetection(imageUri);
const safeSearchResult = batchAnnotateImagesResponse[0].safeSearchAnnotation;
const Likelihood = Vision.protos.google.cloud.vision.v1.Likelihood;
if (Likelihood[safeSearchResult.adult] >= Likelihood.LIKELY ||
Likelihood[safeSearchResult.violence] >= Likelihood.LIKELY) {
functions.logger.log('The image', object.name, 'has been detected as inappropriate.');
return blurImage(object.name);
}
functions.logger.log('The image', object.name, 'has been detected as OK.');
});
שימו לב שהוספנו הגדרה מסוימת של מופע Cloud Functions שיפעיל את הפונקציה. בפקודה .runWith({memory: '2GB'})
, אנחנו מבקשים שהמופע יקבל 2GB של זיכרון במקום ברירת המחדל, כי הפונקציה הזו דורשת הרבה זיכרון.
כשהפונקציה מופעלת, התמונה מועברת דרך Cloud Vision API כדי לזהות אם היא מסומנת כתוכן למבוגרים או כתוכן אלים. אם התמונה מזוהה כלא הולמת על סמך הקריטריונים האלה, אנחנו מטשטשים אותה באמצעות הפונקציה blurImage
, כפי שיוסבר בהמשך.
טשטוש התמונה
מוסיפים את הפונקציה blurImage
הבאה לקובץ index.js
:
index.js
// Blurs the given image located in the given bucket using ImageMagick.
async function blurImage(filePath) {
const tempLocalFile = path.join(os.tmpdir(), path.basename(filePath));
const messageId = filePath.split(path.sep)[1];
const bucket = admin.storage().bucket();
// Download file from bucket.
await bucket.file(filePath).download({destination: tempLocalFile});
functions.logger.log('Image has been downloaded to', tempLocalFile);
// Blur the image using ImageMagick.
await exec(`convert "${tempLocalFile}" -channel RGBA -blur 0x24 "${tempLocalFile}"`);
functions.logger.log('Image has been blurred');
// Uploading the Blurred image back into the bucket.
await bucket.upload(tempLocalFile, {destination: filePath});
functions.logger.log('Blurred image has been uploaded to', filePath);
// Deleting the local file to free up disk space.
fs.unlinkSync(tempLocalFile);
functions.logger.log('Deleted local file.');
// Indicate that the message has been moderated.
await admin.firestore().collection('messages').doc(messageId).update({moderated: true});
functions.logger.log('Marked the image as moderated in the database.');
}
בפונקציה שלמעלה, הנתונים הבינאריים של התמונה מורדים מ-Cloud Storage. לאחר מכן, התמונה מטושטשת באמצעות הכלי convert
של ImageMagick, והגרסה המטושטשת מועלית מחדש לקטגוריית האחסון. לאחר מכן, אנחנו מוחקים את הקובץ במופע של Cloud Functions כדי לפנות מקום בדיסק. אנחנו עושים את זה כי יכול להיות שנעשה שימוש חוזר באותו מופע של Cloud Functions, ואם לא ננקה את הקבצים, יכול להיות שלא יישאר מקום בדיסק. לבסוף, אנחנו מוסיפים להודעה בצ'אט ערך בוליאני שמציין שהתמונה עברה בדיקה, והפעולה הזו תגרום לרענון של ההודעה בצד הלקוח.
פריסת הפונקציה
הפונקציה תהיה פעילה רק אחרי שתבצעו פריסה שלה. בשורת הפקודה, מריצים את הפקודה firebase deploy --only functions
:
firebase deploy --only functions
זה הפלט שיוצג במסוף:
i deploying functions
i functions: ensuring necessary APIs are enabled...
✔ functions: all necessary APIs are enabled
i functions: preparing functions directory for uploading...
i functions: packaged functions (X.XX KB) for uploading
✔ functions: functions folder uploaded successfully
i starting release process (may take several minutes)...
i functions: updating function addWelcomeMessages...
i functions: creating function blurOffensiveImages...
✔ functions[addWelcomeMessages]: Successful update operation.
✔ functions[blurOffensiveImages]: Successful create operation.
✔ functions: all functions deployed successfully!
✔ Deploy complete!
Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview
בדיקת הפונקציה
אחרי שהפונקציה נפרסת בהצלחה:
- פותחים את האפליקציה בדפדפן באמצעות כתובת ה-URL של האירוח (בפורמט
https://<project-id>.firebaseapp.com
). - אחרי שנכנסים לאפליקציה, מעלים תמונה:
- בוחרים את התמונה הכי פוגעת להעלאה (או שאפשר להשתמש בזומבי אוכל בשר הזה!) ואחרי כמה רגעים, הפוסט אמור להתרענן עם גרסה מטושטשת של התמונה:
10. התראות על הודעות חדשות
בקטע הזה תוסיפו Cloud Function ששולח התראות למשתתפים בצ'אט כשמתפרסמת הודעה חדשה.
באמצעות העברת הודעות בענן ב-Firebase (FCM), אתם יכולים לשלוח הודעות למשתמשים בפלטפורמות שונות בצורה מהימנה. כדי לשלוח התראה למשתמש, צריך את אסימון המכשיר שלו ב-FCM. אפליקציית האינטרנט לצ'אט שבה אנחנו משתמשים כבר אוספת טוקנים של מכשירים מהמשתמשים כשהם פותחים את האפליקציה בפעם הראשונה בדפדפן או במכשיר חדש. האסימונים האלה מאוחסנים באוסף fcmTokens
ב-Cloud Firestore.
אם אתם רוצים לדעת איך מקבלים טוקנים של מכשירים ב-FCM באפליקציית אינטרנט, אתם יכולים לעיין ב-Firebase Web Codelab.
שליחת התראות
כדי לזהות מתי מתפרסמות הודעות חדשות, תשתמשו בטריגר functions.firestore.document().onCreate
של Cloud Functions, שמריץ את הקוד שלכם כשנוצר אובייקט חדש בנתיב נתון של Cloud Firestore. מוסיפים את הפונקציה sendNotifications
לקובץ index.js
:
index.js
// Sends a notifications to all users when a new message is posted.
exports.sendNotifications = functions.firestore.document('messages/{messageId}').onCreate(
async (snapshot) => {
// Notification details.
const text = snapshot.data().text;
const payload = {
notification: {
title: `${snapshot.data().name} posted ${text ? 'a message' : 'an image'}`,
body: text ? (text.length <= 100 ? text : text.substring(0, 97) + '...') : '',
icon: snapshot.data().profilePicUrl || '/images/profile_placeholder.png',
click_action: `https://${process.env.GCLOUD_PROJECT}.firebaseapp.com`,
}
};
// Get the list of device tokens.
const allTokens = await admin.firestore().collection('fcmTokens').get();
const tokens = [];
allTokens.forEach((tokenDoc) => {
tokens.push(tokenDoc.id);
});
if (tokens.length > 0) {
// Send notifications to all tokens.
const response = await admin.messaging().sendToDevice(tokens, payload);
await cleanupTokens(response, tokens);
functions.logger.log('Notifications have been sent and tokens cleaned up.');
}
});
בפונקציה שלמעלה, אנחנו אוספים את כל טוקני המכשירים של המשתמשים ממסד הנתונים של Cloud Firestore ושולחים לכל אחד מהם התראה באמצעות הפונקציה admin.messaging().sendToDevice
.
ניקוי האסימונים
לבסוף, נרצה להסיר את הטוקנים שכבר לא תקפים. המצב הזה קורה כשהדפדפן או המכשיר כבר לא משתמשים בטוקן שקיבלנו מהמשתמש. לדוגמה, זה קורה אם המשתמש ביטל את הרשאת ההתראות בסשן הדפדפן. כדי לעשות זאת, מוסיפים את הפונקציה cleanupTokens
הבאה לקובץ index.js
:
index.js
// Cleans up the tokens that are no longer valid.
function cleanupTokens(response, tokens) {
// For each notification we check if there was an error.
const tokensDelete = [];
response.results.forEach((result, index) => {
const error = result.error;
if (error) {
functions.logger.error('Failure sending notification to', tokens[index], error);
// Cleanup the tokens that are not registered anymore.
if (error.code === 'messaging/invalid-registration-token' ||
error.code === 'messaging/registration-token-not-registered') {
const deleteTask = admin.firestore().collection('fcmTokens').doc(tokens[index]).delete();
tokensDelete.push(deleteTask);
}
}
});
return Promise.all(tokensDelete);
}
פריסת הפונקציה
הפונקציה תהיה פעילה רק אחרי שתפרסו אותה. כדי לפרוס אותה, מריצים את הפקודה הבאה בשורת הפקודה:
firebase deploy --only functions
זה הפלט שיוצג במסוף:
i deploying functions
i functions: ensuring necessary APIs are enabled...
✔ functions: all necessary APIs are enabled
i functions: preparing functions directory for uploading...
i functions: packaged functions (X.XX KB) for uploading
✔ functions: functions folder uploaded successfully
i starting release process (may take several minutes)...
i functions: updating function addWelcomeMessages...
i functions: updating function blurOffensiveImages...
i functions: creating function sendNotifications...
✔ functions[addWelcomeMessages]: Successful update operation.
✔ functions[blurOffensiveImages]: Successful updating operation.
✔ functions[sendNotifications]: Successful create operation.
✔ functions: all functions deployed successfully!
✔ Deploy complete!
Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview
בדיקת הפונקציה
- אחרי שהפונקציה נפרסת בהצלחה, פותחים את האפליקציה בדפדפן באמצעות כתובת ה-URL של האירוח (בפורמט
https://<project-id>.firebaseapp.com
). - אם נכנסים לאפליקציה בפעם הראשונה, חשוב לאשר את ההתראות כשמתבקשים לעשות זאת:
- סוגרים את הכרטיסייה של אפליקציית Chat או מציגים כרטיסייה אחרת: ההתראות מופיעות רק אם האפליקציה פועלת ברקע. אם אתם רוצים ללמוד איך לקבל הודעות בזמן שהאפליקציה בחזית, כדאי לעיין בתיעוד שלנו.
- משתמשים בדפדפן אחר (או בחלון פרטי), נכנסים לאפליקציה ומפרסמים הודעה. אמורה להופיע התראה בדפדפן הראשון:
11. כל הכבוד!
השתמשתם ב-Firebase SDK ל-Cloud Functions והוספתם רכיבים בצד השרת לאפליקציית צ'אט.
מה למדנו
- יצירת Cloud Functions באמצעות Firebase SDK for Cloud Functions.
- הפעלת Cloud Functions על סמך אירועים של Auth, Cloud Storage ו-Cloud Firestore.
- מוסיפים תמיכה ב-Firebase Cloud Messaging לאפליקציית האינטרנט.
- פורסים את Cloud Functions באמצעות Firebase CLI.
השלבים הבאים
- מידע על סוגים אחרים של טריגרים של Cloud Functions
- שימוש ב-Firebase וב-Cloud Functions באפליקציה שלכם.