Codelab בנושא AngularFire לאינטרנט

1. סקירה כללית

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

אפליקציית צ'אט שבה משתמשים מדברים על Firebase

מה תלמדו

  • פיתוח אפליקציית אינטרנט באמצעות Angular ו-Firebase.
  • סנכרון נתונים באמצעות Cloud Firestore ו-Cloud Storage ל-Firebase.
  • אימות המשתמשים באמצעות אימות ב-Firebase.
  • פריסת אפליקציית האינטרנט ב-Firebase App Hosting.
  • שליחת התראות באמצעות Firebase Cloud Messaging.
  • אוספים את נתוני הביצועים של אפליקציית האינטרנט.

מה צריך

  • חשבון GitHub
  • היכולת לשדרג את פרויקט Firebase לתוכנית התמחור Blaze
  • סביבת הפיתוח המשולבת (IDE) או עורך הטקסט שבחרתם, כמו WebStorm,‏ Sublime או VS Code
  • מנהל החבילות npm, שמגיע בדרך כלל עם Node.js
  • מסוף/מסוף
  • דפדפן לבחירתכם, כמו Chrome
  • קוד לדוגמה ב-Codelab (כדי לקבל את הקוד, עיינו בשלב הבא ב-Codelab).

2. קבלת קוד לדוגמה

יצירת מאגר ב-GitHub

קוד המקור של ה-codelab נמצא בכתובת https://github.com/firebase/codelab-friendlychat-web. המאגר מכיל פרויקטים לדוגמה לכמה פלטפורמות. עם זאת, ב-codelab הזה נעשה שימוש רק בספרייה angularfire-start.

מעתיקים את התיקייה angularfire-start למאגר שלכם:

  1. באמצעות מסוף, יוצרים תיקייה חדשה במחשב ועוברים לספרייה החדשה:
    mkdir codelab-friendlyeats-web
    
    cd codelab-friendlyeats-web
    
  2. משתמשים בחבילת ה-npm‏ giget כדי לאחזר רק את התיקייה angularfire-start:
    npx giget@latest gh:firebase/codelab-friendlychat-web/angularfire-start#master . --install
    
  3. מעקב אחר שינויים באופן מקומי באמצעות git:
    git init
    
    git add .
    
    git commit -m "codelab starting point"
    
    git branch -M main
    
  4. יוצרים מאגר חדש ב-GitHub: https://github.com/new. נותנים לו שם.
    1. ב-GitHub תקבלו כתובת URL חדשה של המאגר שנראית כך: https://github.com/[user-name]/[repository-name].git או git@github.com:[user-name]/[repository-name].git. מעתיקים את כתובת ה-URL הזו.
  5. דוחפים את השינויים המקומיים למאגר החדש ב-GitHub. מריצים את הפקודה הבאה, ומחליפים את ערך placeholder‏ your-repository-url בכתובת ה-URL של המאגר.
    git remote add origin your-repository-url
    
    git push -u origin main
    
  6. עכשיו הקוד הבסיסי אמור להופיע במאגר שלכם ב-GitHub.

3. יצירת פרויקט Firebase והגדרתו

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

  1. נכנסים למסוף Firebase.
  2. במסוף Firebase, לוחצים על Add Project (הוספת פרויקט) ומזינים את השם FriendlyChat לפרויקט ב-Firebase. חשוב לזכור את מזהה הפרויקט ב-Firebase.
  3. מבטלים את הסימון של האפשרות הפעלת Google Analytics בפרויקט הזה.
  4. לוחצים על Create Project.

באפליקציה שתבנו נעשה שימוש במוצרי Firebase שזמינים לאפליקציות אינטרנט:

  • אימות ב-Firebase כדי לאפשר למשתמשים להיכנס לאפליקציה בקלות.
  • Cloud Firestore כדי לשמור נתונים מובְנים בענן ולקבל התראות מיידיות כשהנתונים משתנים.
  • Cloud Storage for Firebase לשמירת קבצים בענן.
  • Firebase App Hosting ליצירה, לאירוח ולפרסום של האפליקציה.
  • העברת הודעות בענן ב-Firebase כדי לשלוח התראות ב-push ולהציג התראות קופצות בדפדפן.
  • מעקב אחר ביצועים ב-Firebase כדי לאסוף נתוני ביצועים של משתמשים באפליקציה.

חלק מהמוצרים האלה דורשים הגדרה מיוחדת או צריך להפעיל אותם באמצעות מסוף Firebase.

שדרוג של תוכנית התמחור ב-Firebase

כדי להשתמש ב-Firebase App Hosting וב-Cloud Storage for Firebase, פרויקט Firebase צריך להיות בתוכנית התמחור 'תשלום לפי שימוש' (Blaze), כלומר הוא צריך להיות מקושר לחשבון לחיוב ב-Cloud.

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

כדי לשדרג את הפרויקט לתוכנית Blaze:

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

הוספת אפליקציית אינטרנט של Firebase לפרויקט

  1. לוחצים על סמל האינטרנט 58d6543a156e56f9.png כדי ליצור אפליקציית אינטרנט חדשה ב-Firebase.
  2. רושמים את האפליקציה עם הכינוי Friendly Chat. לא מסמנים את התיבה לצד Also set up Firebase Hosting for this app (גם להגדיר אירוח ב-Firebase לאפליקציה הזו). לוחצים על Register app (רישום האפליקציה).
  3. בשלב הבא יופיע אובייקט תצורה. אין צורך בו כרגע. לוחצים על Continue to console.

צילום מסך של אפליקציית האינטרנט לצורך רישום

הגדרת אימות

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

  1. במסוף Firebase, עוברים אל Authentication.
  2. לוחצים על תחילת העבודה.
  3. בעמודה ספקים נוספים, לוחצים על Google > הפעלה.
  4. בתיבת הטקסט Public-facing name for project, מזינים שם שקל לזכור, למשל My Next.js app.
  5. בתפריט הנפתח Support email for project, בוחרים את כתובת האימייל שלכם.
  6. לוחצים על שמירה.

הגדרת Cloud Firestore

אפליקציית האינטרנט משתמשת ב-Cloud Firestore כדי לשמור הודעות צ'אט ולקבל הודעות צ'אט חדשות.

כך מגדירים את Cloud Firestore בפרויקט Firebase:

  1. בחלונית הימנית של מסוף Firebase, מרחיבים את Build ובוחרים באפשרות Firestore database.
  2. לוחצים על Create database.
  3. משאירים את הערך (default) בשדה Database ID.
  4. בוחרים מיקום למסד הנתונים ולוחצים על הבא.
    באפליקציה אמיתית, כדאי לבחור מיקום קרוב למשתמשים.
  5. לוחצים על התחלה במצב בדיקה. קוראים את כתב הוויתור לגבי כללי האבטחה.
    בהמשך הסדנה תוסיפו כללי אבטחה כדי לאבטח את הנתונים. אסור להפיץ או לחשוף אפליקציה באופן ציבורי בלי להוסיף כללי אבטחה למסד הנתונים.
  6. לוחצים על יצירה.

הגדרת Cloud Storage for Firebase

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

כך מגדירים את Cloud Storage for Firebase בפרויקט Firebase:

  1. בחלונית הימנית של מסוף Firebase, מרחיבים את Build ובוחרים באפשרות Storage.
  2. לוחצים על תחילת העבודה.
  3. בוחרים מיקום לקטגוריית ברירת המחדל של האחסון.
    קטגוריות ב-US-WEST1, ב-US-CENTRAL1 וב-US-EAST1 יכולות ליהנות מהתוכנית 'תמיד בחינם' ב-Google Cloud Storage. קטגוריות בכל המיקומים האחרים כפופות לתמחור ולשימוש ב-Google Cloud Storage.
  4. לוחצים על התחלה במצב בדיקה. קוראים את כתב הוויתור לגבי כללי האבטחה.
    בהמשך הסדנה תוסיפו כללי אבטחה כדי לאבטח את הנתונים. אין להפיץ או לחשוף אפליקציה באופן ציבורי בלי להוסיף כללי אבטחה לקטגוריית האחסון.
  5. לוחצים על יצירה.

4. התקנה של ממשק שורת הפקודה של Firebase

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

  1. כדי להתקין את ה-CLI, מריצים את פקודת ה-npm הבאה:
npm -g install firebase-tools@latest
  1. מריצים את הפקודה הבאה כדי לוודא שה-CLI הוטמע כמו שצריך:
firebase --version

מוודאים שגרסת ה-CLI של Firebase היא 13.9.0 ואילך.

  1. מריצים את הפקודה הבאה כדי להעניק הרשאה ל-CLI של Firebase:
firebase login

הגדרתם את התבנית של אפליקציית האינטרנט כדי למשוך את ההגדרות של האפליקציה ל-Firebase Hosting מהספרייה המקומית של האפליקציה (המאגר ששכפלתם מוקדם יותר ב-codelab). עם זאת, כדי לשלוף את ההגדרות, צריך לשייך את האפליקציה לפרויקט Firebase.

  1. צריך לוודא ששורת הפקודה ניגשת לספרייה המקומית angularfire-start של האפליקציה.
  2. כדי לשייך את האפליקציה לפרויקט Firebase, מריצים את הפקודה הבאה:
firebase use --add
  1. כשמופיעה בקשה, בוחרים את מזהה הפרויקט ומעניקים לפרופקט ב-Firebase כינוי.

כתובת אימייל חלופית שימושית אם יש לכם כמה סביבות (ייצור, Staging וכו'). עם זאת, ב-codelab הזה נשתמש רק בכינוי default.

  1. פועלים לפי שאר ההוראות בשורת הפקודה.

5. התקנת AngularFire

לפני שמפעילים את הפרויקט, צריך לוודא שהגדרתם את Angular CLI ואת AngularFire.

  1. מריצים את הפקודה הבאה במסוף:
npm install -g @angular/cli
  1. לאחר מכן, במסוף מהספרייה angularfire-start, מריצים את הפקודה הבאה של Angular CLI:
ng add @angular/fire

הפעולה הזו תתקין את כל הרכיבים התלויים הנדרשים לפרויקט.

  1. כשמוצגת בקשה, מבטלים את הסימון של ng deploy -- hosting באמצעות מקש הרווח. מקישים על מקשי החיצים ועל מקש הרווח כדי לבחור את התכונות הבאות:
    • Authentication
    • Firestore
    • Cloud Messaging
    • Cloud Storage
  2. לוחצים על enter ופועלים לפי שאר ההוראות.
  3. יוצרים השמירה עם הודעת השמירה 'Install AngularFire' ומעבירים אותה למאגר ב-GitHub.

6. יצירת קצה עורפי של אירוח אפליקציות

בקטע הזה תגדירו קצה עורפי של אירוח אפליקציות כדי לעקוב אחרי הסתעפות במאגר ה-Git.

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

  1. עוברים אל הדף App Hosting במסוף Firebase:

מצב אפס במסוף App Hosting, עם הלחצן 'תחילת העבודה'

  1. לוחצים על 'תחילת העבודה' כדי להתחיל בתהליך היצירה של הקצה העורפי. מגדירים את הקצה העורפי באופן הבא:
  2. פועלים לפי ההנחיות בשלב הראשון כדי לחבר את מאגר GitHub שיצרתם מקודם.
  3. מגדירים את הגדרות הפריסה:
    1. השארת ספריית השורש כ-/
    2. מגדירים את ההסתעפות הפעילה ל-main
    3. הפעלת השקות אוטומטיות
  4. נותנים שם לקצה העורפי friendlychat-codelab.
  5. בקטע 'יצירה או שיוך של אפליקציית אינטרנט ב-Firebase', בוחרים את אפליקציית האינטרנט שהגדרתם מקודם בתפריט הנפתח 'בחירת אפליקציית אינטרנט קיימת ב-Firebase'.
  6. לוחצים על 'סיום ופריסה'. אחרי רגע, תועברו לדף חדש שבו תוכלו לראות את הסטטוס של הקצה העורפי החדש של אירוח האפליקציות.
  7. בסיום ההשקה, לוחצים על הדומיין החינמי בקטע 'דומיינים'. יכול להיות שיחלפו כמה דקות עד שהשינוי יתחיל לפעול בגלל הפצת ה-DNS.

פרסתם את אפליקציית האינטרנט הראשונית! בכל פעם שתשלחו גרסה חדשה להטמעה להסתעפות main במאגר GitHub, תראו שההרצה החדשה וההשקה מתחילות במסוף Firebase, והאתר יתעדכן באופן אוטומטי בסיום ההשקה.

מצב אפס במסוף App Hosting, עם הלחצן 'תחילת העבודה'

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

האפליקציה לא יכולה לעשות שום דבר כרגע, אבל בעזרתכם היא תוכל לעשות זאת בקרוב!

עכשיו נבנה אפליקציית צ'אט בזמן אמת.

7. ייבוא והגדרה של Firebase

הגדרת Firebase

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

  1. עוברים אל הגדרות הפרויקט במסוף Firebase.
  2. בכרטיס 'האפליקציות שלך', בוחרים את הכינוי של האפליקציה שעבורה צריך אובייקט תצורה.
  3. בוחרים באפשרות 'Config' (הגדרה) בחלונית של קטע הקוד של Firebase SDK.

תוכלו לראות שקובץ הסביבה /angularfire-start/src/environments/environment.ts נוצר בשבילכם.

  1. מעתיקים את קטע הקוד של אובייקט התצורה ומוסיפים אותו לקובץ angularfire-start/src/firebase-config.js.

environment.ts

export const environment = {
  firebase: {
    apiKey: "API_KEY",
    authDomain: "PROJECT_ID.firebaseapp.com",
    projectId: "PROJECT_ID",
    storageBucket: "PROJECT_ID.firebasestorage.app",
    messagingSenderId: "SENDER_ID",
    appId: "APP_ID",
  },
};

הצגת ההגדרה של AngularFire

תוכלו לראות שהתכונות שבחרתם במסוף נוספו באופן אוטומטי לקובץ /angularfire-start/src/app/app.config.ts. כך האפליקציה תוכל להשתמש בתכונות ובפונקציות של Firebase.

8. הגדרת כניסה של משתמשים

עכשיו AngularFire אמור להיות מוכן לשימוש, כי הוא יובא ויאופס ב-app.config.ts. עכשיו נטמיע כניסה של משתמשים באמצעות אימות ב-Firebase.

הוספת דומיין מורשה

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

  1. עוברים אל App Hosting.
  2. מעתיקים את הדומיין של הקצה העורפי.
  3. עוברים אל הגדרות אימות.
  4. בוחרים בכרטיסייה דומיינים מורשים.
  5. לוחצים על Add domain (הוספת דומיין) ומדביקים את הדומיין של הקצה העורפי של אירוח האפליקציות.

אימות המשתמשים באמצעות כניסה באמצעות חשבון Google

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

  1. בספריית המשנה /src/app/services/, פותחים את chat.service.ts.
  2. מאתרים את הפונקציה login.
  3. מחליפים את כל הפונקציה בקוד הבא.

chat.service.ts

// Signs-in Friendly Chat.
login() {
    signInWithPopup(this.auth, this.provider).then((result) => {
        const credential = GoogleAuthProvider.credentialFromResult(result);
        this.router.navigate(['/', 'chat']);
        return credential;
    })
}

הפונקציה logout מופעלת כשהמשתמש לוחץ על הלחצן Log out (יציאה מהחשבון).

  1. חוזרים לקובץ src/app/services/chat.service.ts.
  2. מאתרים את הפונקציה logout.
  3. מחליפים את כל הפונקציה בקוד הבא.

chat.service.ts

// Logout of Friendly Chat.
logout() {
    signOut(this.auth).then(() => {
        this.router.navigate(['/', 'login'])
        console.log('signed out');
    }).catch((error) => {
        console.log('sign out error: ' + error);
    })
}

מעקב אחר מצב האימות

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

  1. חוזרים לקובץ src/app/services/chat.service.ts.
  2. מאתרים את הקצאת המשתנה user$.

chat.service.ts

// observable that is updated when the auth state changes
user$ = user(this.auth);

הקוד שלמעלה קורא לפונקציה user של AngularFire שמחזירה משתמש שניתן לצפות בו. הוא יופעל בכל פעם שמצב האימות ישתנה (כשהמשתמש נכנס או יוצא מהחשבון). רכיבי התבניות של Angular ב-FriendlyChat משתמשים באירוע הנצפה הזה כדי לעדכן את ממשק המשתמש להפניה אוטומטית, להציג את המשתמש בתפריט הניווט בכותרת וכו'.

בדיקת ההתחברות לאפליקציה

  1. יוצרים השמירה עם הודעת השמירה 'הוספת אימות Google' ומעבירים אותה למאגר ב-GitHub.
  2. פותחים את הדף App Hosting במסוף Firebase וממתינים להשלמת ההשקה החדשה.
  3. באפליקציית האינטרנט, מרעננים את הדף ונכנסים לאפליקציה באמצעות לחצן הכניסה וחשבון Google. אם מופיעה הודעת השגיאה auth/operation-not-allowed, צריך לוודא שהפעלתם את 'כניסה באמצעות חשבון Google' כספק אימות במסוף Firebase.
  4. אחרי הכניסה, תמונת הפרופיל ושם המשתמש שלכם אמורים להופיע: angularfire-3.png

9. כתיבת הודעות ב-Cloud Firestore

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

מודל נתונים

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

688d7bc5fb662b57.png

הוספת הודעות ל-Cloud Firestore

כדי לאחסן את הודעות הצ'אט שנכתבות על ידי המשתמשים, תשתמשו ב-Cloud Firestore.

בקטע הזה תוסיפו את הפונקציונליות שמאפשרת למשתמשים לכתוב הודעות חדשות במסד הנתונים. לחיצה של משתמש על הלחצן SEND תפעיל את קטע הקוד הבא. הפונקציה מוסיפה אובייקט הודעה עם התוכן של שדות ההודעה למכונה שלכם ב-Cloud Firestore באוסף messages. השיטה add() מוסיפה לאוסף מסמך חדש עם מזהה שנוצר באופן אוטומטי.

  1. חוזרים לקובץ src/app/services/chat.service.ts.
  2. מאתרים את הפונקציה addMessage.
  3. מחליפים את כל הפונקציה בקוד הבא.

chat.service.ts

// Adds a text or image message to Cloud Firestore.
addMessage = async (
  textMessage: string | null,
  imageUrl: string | null,
): Promise<void | DocumentReference<DocumentData>> => {
  // ignore empty messages
  if (!textMessage && !imageUrl) {
    console.log(
      "addMessage was called without a message",
      textMessage,
      imageUrl,
    );
    return;
  }

  if (this.currentUser === null) {
    console.log("addMessage requires a signed-in user");
    return;
  }

  const message: ChatMessage = {
    name: this.currentUser.displayName,
    profilePicUrl: this.currentUser.photoURL,
    timestamp: serverTimestamp(),
    uid: this.currentUser?.uid,
  };

  textMessage && (message.text = textMessage);
  imageUrl && (message.imageUrl = imageUrl);

  try {
    const newMessageRef = await addDoc(
      collection(this.firestore, "messages"),
      message,
    );
    return newMessageRef;
  } catch (error) {
    console.error("Error writing new message to Firebase Database", error);
    return;
  }
};

בדיקת שליחת הודעות

  1. יוצרים השמירה עם הודעת ההסבר 'פרסום צ'אטים חדשים ב-Firestore' ומעבירים אותה למאגר ב-GitHub.
  2. פותחים את הדף App Hosting במסוף Firebase וממתינים להשלמת ההשקה החדשה.
  3. מרעננים את FriendlyChat. אחרי הכניסה לחשבון, מזינים הודעה כמו 'היי' ולוחצים על שליחה. הפונקציה הזו תכתוב את ההודעה ב-Cloud Firestore. עם זאת, עדיין לא תראו את הנתונים באפליקציית האינטרנט בפועל, כי עדיין צריך להטמיע את אחזור הנתונים (הקטע הבא בקודלאב).
  4. ההודעה החדשה תופיע במסוף Firebase. פותחים את ממשק המשתמש של חבילת האפליקציות של ה-Emulator. בקטע Build, לוחצים על Firestore Database (או לוחצים כאן). האוסף messages עם ההודעה החדשה שהוספתם אמור להופיע:

6812efe7da395692.png

10. קריאת ההודעות

סנכרון הודעות

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

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

  1. חוזרים לקובץ src/app/services/chat.service.ts.
  2. מאתרים את הפונקציה loadMessages.
  3. מחליפים את כל הפונקציה בקוד הבא.

chat.service.ts

// Loads chat message history and listens for upcoming ones.
loadMessages = () => {
  // Create the query to load the last 12 messages and listen for new ones.
  const recentMessagesQuery = query(collection(this.firestore, 'messages'), orderBy('timestamp', 'desc'), limit(12));
  // Start listening to the query.
  return collectionData(recentMessagesQuery);
}

כדי להאזין להודעות במסד הנתונים, יוצרים שאילתות בקולקציה באמצעות הפונקציה collection כדי לציין באיזו קולקציה נמצאים הנתונים שרוצים להאזין להם. בקוד שלמעלה, אתם מקשיב לשינויים באוסף messages, שבו מאוחסנות הודעות הצ'אט. אתם גם מחילים הגבלה על ידי האזנה ל-12 ההודעות האחרונות בלבד באמצעות limit(12) והזמנת ההודעות לפי תאריך באמצעות orderBy('timestamp', 'desc') כדי לקבל את 12 ההודעות החדשות ביותר.

בפונקציה collectionData נעשה שימוש בתמונות מצב (snapshots) ברקע. פונקציית הקריאה החוזרת מופעלת כשיש שינויים במסמכים שתואמים לשאילתה. למשל, אם הודעה נמחקת, משתנה או מתווספת. מידע נוסף זמין במסמכי העזרה של Cloud Firestore.

בדיקת סנכרון ההודעות

  1. יוצרים השמירה עם הודעת השמירה 'הצגת צ'אטים חדשים בממשק המשתמש' ומעבירים אותה למאגר ב-GitHub.
  2. פותחים את הדף App Hosting במסוף Firebase וממתינים להשלמת ההשקה החדשה.
  3. מרעננים את FriendlyChat. ההודעות שיצרתם קודם לכן במסד הנתונים אמורות להופיע בממשק המשתמש של FriendlyChat (ראו בהמשך). אפשר לכתוב הודעות חדשות, והן אמורות להופיע באופן מיידי.
  4. (אופציונלי) אפשר לנסות למחוק, לשנות או להוסיף הודעות חדשות באופן ידני ישירות בקטע Firestore בחבילת ה-Emulator. השינויים אמורים להופיע בממשק המשתמש.

כל הכבוד! אתם קוראים מסמכים של Cloud Firestore באפליקציה שלכם.

angularfire-2.png

11. הוספת תכונות מבוססות-AI

תשתמשו ב-AI מבית Google כדי להוסיף לאפליקציית הצ'אט תכונות עזר שימושיות.

קבלת מפתח Google AI API

  1. עוברים אל Google AI Studio ולוחצים על Create API key (יצירת מפתח API).
  2. בוחרים את פרויקט Firebase שיצרתם לקודלאב הזה. ההנחיה היא לפרויקט ב-Google Cloud, אבל כל פרויקט ב-Firebase הוא פרויקט ב-Google Cloud.
  3. לוחצים על Create API key in existing project (יצירת מפתח API בפרויקט קיים).
  4. מעתיקים את מפתח ה-API שנוצר

התקנה של תוסף

התוסף הזה פורס פונקציית Cloud שתופעל בכל פעם שמסמך חדש יתווסף לאוסף messages ב-Firestore. הפונקציה תפנה ל-Gemini ותכתוב את התשובה שלו בשדה response במסמך.

  1. לוחצים על Install in Firebase console (התקנה במסוף Firebase) בדף התוסף Build Chatbot with the Gemini API (פיתוח צ'אטבוט באמצעות Gemini API).
  2. פועלים לפי ההנחיות. בשלב Configure extension (הגדרת התוסף), מגדירים את ערכי הפרמטרים הבאים:
    • ספק Gemini API: Google AI
    • מפתח API של Google AI: מדביקים את המפתח שיצרתם קודם ולוחצים על Create secret.
    • נתיב האוסף ב-Firestore: messages
    • שדה ההנחיה: text
    • שדה התגובה: response
    • שדה ההזמנה: timestamp
    • הקשר: Keep your answers short, informal, and helpful. Use emojis when possible.
  3. לוחצים על התקנת התוסף.
  4. ממתינים לסיום ההתקנה של התוסף.

בדיקת התכונה מבוססת-ה-AI

ב-FriendlyChat כבר יש קוד לקריאת תשובות מתוסף ה-AI. כל מה שצריך לעשות הוא לשלוח הודעה חדשה בצ'אט כדי לבדוק את זה.

  1. פותחים את FriendlyChat ושולחים הודעה.
  2. אחרי כמה רגעים, תופיע תגובה בחלון קופץ לצד ההודעה שלכם. בסוף התיאור מופיעה ההערה ✨ ai generated כדי להבהיר שהוא נוצר באמצעות AI גנרטיבי, ולא על ידי משתמש אמיתי.

12. שליחת תמונות

עכשיו נוסיף תכונה לשיתוף תמונות.

Cloud Firestore מתאים לאחסון נתונים מובְנים, אבל Cloud Storage מתאים יותר לאחסון קבצים. Cloud Storage for Firebase הוא שירות אחסון קבצים/blob, שבו תשתמשו כדי לאחסן תמונות שמשתמשים משתפים באמצעות האפליקציה.

שמירת תמונות ב-Cloud Storage

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

  1. המערכת יוצרת הודעה 'Placeholder' בצ'אט בפיד, כדי שהמשתמשים יראו אנימציה של 'טעינה' בזמן העלאת התמונה.
  2. העלאת קובץ התמונה ל-Cloud Storage בנתיב הזה: /<uid>/<file_name>
  3. יוצרת כתובת URL של קובץ התמונה שגלויה לכולם.
  4. המערכת מעדכנת את הודעת הצ'אט בכתובת ה-URL של קובץ התמונה החדש שהועלה, במקום בתמונת הטעינה הזמנית.

עכשיו מוסיפים את הפונקציונליות לשליחת תמונה:

  1. חוזרים לקובץ src/chat.service.ts.
  2. מאתרים את הפונקציה saveImageMessage.
  3. מחליפים את כל הפונקציה בקוד הבא.

chat.service.ts

// Saves a new message containing an image in Firestore.
// This first saves the image in Firebase storage.
saveImageMessage = async(file: any) => {
  try {
    // 1 - Add a message with a loading icon that will get updated with the shared image.
    const messageRef = await this.addMessage(null, this.LOADING_IMAGE_URL);

    // 2 - Upload the image to Cloud Storage.
    const filePath = `${this.auth.currentUser?.uid}/${file.name}`;
    const newImageRef = ref(this.storage, filePath);
    const fileSnapshot = await uploadBytesResumable(newImageRef, file);

    // 3 - Generate a public URL for the file.
    const publicImageUrl = await getDownloadURL(newImageRef);

    // 4 - Update the chat message placeholder with the image's URL.
    messageRef ?
    await updateDoc(messageRef, {
      imageUrl: publicImageUrl,
      storageUri: fileSnapshot.metadata.fullPath
    }): null;
  } catch (error) {
    console.error('There was an error uploading a file to Cloud Storage:', error);
  }
}

בדיקת שליחת תמונות

  1. יוצרים השמירה עם הודעת השמירה 'הוספת היכולת לפרסם תמונות' ומעבירים אותה למאגר ב-GitHub.
  2. פותחים את הדף App Hosting במסוף Firebase וממתינים להשלמת ההשקה החדשה.
  3. מרעננים את FriendlyChat. אחרי הכניסה לחשבון, לוחצים על לחצן העלאת התמונה בפינה הימנית התחתונה angularfire-4.png ובוחרים קובץ תמונה באמצעות בורר הקבצים. אם אתם מחפשים תמונה, אפשר להשתמש בתמונה היפה הזו של כוס קפה.
  4. אמורה להופיע הודעה חדשה בממשק המשתמש של האפליקציה עם התמונה שבחרתם: angularfire-2.png

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

13. Show notifications – הצגת ההתראות

עכשיו תוסיפו תמיכה בהתראות בדפדפן. האפליקציה תודיע למשתמשים כשיפורסמו הודעות חדשות בצ'אט. Firebase Cloud Messaging‏ (FCM) הוא פתרון להעברת הודעות בפלטפורמות שונות, שמאפשר לשלוח הודעות והתראות בצורה מהימנה ללא עלות.

הוספת ה-service worker של FCM

אפליקציית האינטרנט צריכה קובץ שירות (service worker) שיקבל ויציג התראות באינטרנט.

ספק ההודעות אמור להיות מוגדר כבר כש-AngularFire נוסף. צריך לוודא שהקוד הבא קיים בקטע הייבוא של /angularfire-start/src/app/app.config.ts

provideMessaging(() => {
    return getMessaging();
}),

app/app.config.ts

פשוט צריך לטעון את ה-SDK של Firebase Cloud Messaging ולהפעיל אותו, והוא ידאג להציג את ההתראות.

איך מקבלים אסימוני מכשיר של FCM

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

כשהמשתמש נכנס לחשבון, צריך להפעיל את הפונקציה saveMessagingDeviceToken. כאן תקבלו את אסימון המכשיר של FCM מהדפדפן ותשמרו אותו ב-Cloud Firestore.

chat.service.ts

  1. מאתרים את הפונקציה saveMessagingDeviceToken.
  2. מחליפים את כל הפונקציה בקוד הבא.

chat.service.ts

// Saves the messaging device token to Cloud Firestore.
saveMessagingDeviceToken= async () => {
    try {
      const currentToken = await getToken(this.messaging);
      if (currentToken) {
        console.log('Got FCM device token:', currentToken);
        // Saving the Device Token to Cloud Firestore.
        const tokenRef = doc(this.firestore, 'fcmTokens', currentToken);
        await setDoc(tokenRef, { uid: this.auth.currentUser?.uid });
 
        // This will fire when a message is received while the app is in the foreground.
        // When the app is in the background, firebase-messaging-sw.js will receive the message instead.
        onMessage(this.messaging, (message) => {
          console.log(
            'New foreground notification from Firebase Messaging!',
            message.notification
          );
        });
      } else {
        // Need to request permissions to show notifications.
        this.requestNotificationsPermissions();
      }
    } catch(error) {
      console.error('Unable to get messaging token.', error);
    };
}

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

בקשת הרשאות להצגת התראות

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

8b9d0c66dc36153d.png

  1. חוזרים לקובץ src/app/services/chat.service.ts.
  2. מאתרים את הפונקציה requestNotificationsPermissions.
  3. מחליפים את כל הפונקציה בקוד הבא.

chat.service.ts

// Requests permissions to show notifications.
requestNotificationsPermissions = async () => {
    console.log('Requesting notifications permission...');
    const permission = await Notification.requestPermission();
    
    if (permission === 'granted') {
      console.log('Notification permission granted.');
      // Notification permission granted.
      await this.saveMessagingDeviceToken();
    } else {
      console.log('Unable to get permission to notify.');
    }
}

איך מקבלים אסימון מכשיר

  1. יוצרים השמירה עם הודעת השמירה 'הוספת היכולת לפרסם תמונות' ומעבירים אותה למאגר ב-GitHub.
  2. פותחים את הדף App Hosting במסוף Firebase וממתינים להשלמת ההשקה החדשה.
  3. מרעננים את FriendlyChat. אחרי ההתחברות, אמורה להופיע תיבת הדו-שיח של הרשאת ההתראות: bd3454e6dbfb6723.png
  4. לוחצים על אישור.
  5. פותחים את מסוף JavaScript בדפדפן. אמורה להופיע ההודעה הבאה: Got FCM device token: cWL6w:APA91bHP...4jDPL_A-wPP06GJp1OuekTaTZI5K2Tu
  6. מעתיקים את אסימון המכשיר. תצטרכו אותו בשלב הבא של הקודלאב.

שליחת התראה למכשיר

עכשיו, אחרי שקיבלתם את אסימון המכשיר, אתם יכולים לשלוח התראה.

  1. פותחים את הכרטיסייה Cloud Messaging במסוף Firebase.
  2. לוחצים על 'התראה חדשה'.
  3. מזינים כותרת והודעה.
  4. בצד שמאל של המסך, לוחצים על 'שליחת הודעת בדיקה'.
  5. מזינים את אסימון המכשיר שהעתקתם מלוח JavaScript בדפדפן, ואז לוחצים על סימן הפלוס ("+").
  6. לוחצים על 'בדיקה'.

אם האפליקציה נמצאת בחזית, ההודעה תופיע במסוף JavaScript.

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

de79e8638a45864c.png

14. כללי אבטחה של Cloud Firestore

הצגת כללי אבטחה של מסד נתונים

ב-Cloud Firestore נעשה שימוש בשפת כללים ספציפית כדי להגדיר הרשאות גישה, אבטחה ואימות נתונים.

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

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

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write;
    }
  }
}

כדי להגביל דברים, תעדכנו את הכללים באמצעות הכללים הבאים:

firestore.rules

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    // Messages:
    //   - Anyone can read.
    //   - Authenticated users can add and edit messages.
    //   - Validation: Check name is same as auth token and text length below 300 char or that imageUrl is a URL.
    //   - Deletes are not allowed.
    match /messages/{messageId} {
      allow read;
      allow create, update: if request.auth != null
                    && request.resource.data.name == request.auth.token.name
                    && (request.resource.data.text is string
                      && request.resource.data.text.size() <= 300
                      || request.resource.data.imageUrl is string
                      && request.resource.data.imageUrl.matches('https?://.*'));
      allow delete: if false;
    }
    // FCM Tokens:
    //   - Anyone can write their token.
    //   - Reading list of tokens is not allowed.
    match /fcmTokens/{token} {
      allow read: if false;
      allow write;
    }
  }
}

כללי האבטחה אמורים להתעדכן באופן אוטומטי בחבילת ה-Emulator.

הצגת כללי האבטחה של Cloud Storage

ב-Cloud Storage for Firebase נעשה שימוש בשפת כללים ספציפית כדי להגדיר את הרשאות הגישה, האבטחה ואימות הנתונים.

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

rules_version = '2';

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

תעדכנו את הכללים כדי לבצע את הפעולות הבאות:

  • לאפשר לכל משתמש לכתוב רק בתיקיות הספציפיות שלו
  • מתן הרשאת קריאה לכולם ב-Cloud Storage
  • חשוב לוודא שהקבצים שהועלו הם תמונות
  • להגביל את גודל התמונות שניתן להעלות ל-5MB לכל היותר

אפשר להטמיע את זה באמצעות הכללים הבאים:

storage.rules

rules_version = '2';

// Returns true if the uploaded file is an image and its size is below the given number of MB.
function isImageBelowMaxSize(maxSizeMB) {
  return request.resource.size < maxSizeMB * 1024 * 1024
      && request.resource.contentType.matches('image/.*');
}

service firebase.storage {
  match /b/{bucket}/o {
    match /{userId}/{messageId}/{fileName} {
      allow write: if request.auth != null && request.auth.uid == userId && isImageBelowMaxSize(5);
      allow read;
    }
  }
}

15. כל הכבוד!

השתמשתם ב-Firebase כדי ליצור אפליקציית אינטרנט לצ'אט בזמן אמת!

מה נכלל

  • Firebase App Hosting
  • אימות ב-Firebase
  • Cloud Firestore
  • Firebase SDK ל-Cloud Storage
  • העברת הודעות בענן ב-Firebase
  • מעקב אחר ביצועים ב-Firebase

השלבים הבאים

מידע נוסף

16. [אופציונלי] אכיפה באמצעות בדיקת אפליקציה

בדיקת האפליקציה של Firebase עוזרת לאבטח את השירותים מפני תנועה לא רצויה, ומגינה על הקצה העורפי מפני ניצול לרעה. בשלב הזה תוסיפו אימות פרטי כניסה ותחסמו לקוחות לא מורשים באמצעות App Check ו-reCAPTCHA Enterprise.

קודם כול, צריך להפעיל את App Check ואת reCaptcha.

הפעלת reCaptcha Enterprise

  1. במסוף Cloud, מחפשים את reCaptcha Enterprise בקטע Security ובוחרים בו.
  2. מפעילים את השירות לפי ההנחיות ולוחצים על Create Key.
  3. מזינים שם לתצוגה כשמופיעה ההודעה הרלוונטית ובוחרים באפשרות אתר כסוג הפלטפורמה.
  4. מוסיפים את כתובות ה-URL שנפרסו לרשימת הדומיינים, ומוודאים שהאפשרות 'שימוש באתגר של תיבת סימון' לא מסומנת.
  5. לוחצים על Create Key ושומרים את המפתח שנוצר במקום בטוח. תצטרכו אותו בהמשך השלב הזה.

הפעלת App Check

  1. במסוף Firebase, מאתרים את הקטע Build בחלונית השמאלית.
  2. לוחצים על בדיקת האפליקציה ואז על הכרטיסייה שיטת הכניסה כדי לעבור אל בדיקת האפליקציה.
  3. לוחצים על Register (רישום) ומזינים את המפתח של reCaptcha Enterprise כשמופיעה בקשה לעשות זאת, ואז לוחצים על Save (שמירה).
  4. בתצוגת ממשקי ה-API, בוחרים באפשרות Storage ולוחצים על Enforce. חוזרים על הפעולה עבור Cloud Firestore.

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

Uncaught Error in snapshot listener: FirebaseError: [code=permission-denied]: Missing or insufficient permissions.

המשמעות היא ש-App Check חוסם בקשות שלא אומתו כברירת מחדל. עכשיו נוסיף לאפליקציה אימות.

עוברים לקובץ environment.ts ומוסיפים את reCAPTCHAEnterpriseKey לאובייקט environment.

export const environment = {
  firebase: {
    apiKey: 'API_KEY',
    authDomain: 'PROJECT_ID.firebaseapp.com',
    databaseURL: 'https://PROJECT_ID.firebaseio.com',
    projectId: 'PROJECT_ID',
    storageBucket: 'PROJECT_ID.firebasestorage.app',
    messagingSenderId: 'SENDER_ID',
    appId: 'APP_ID',
    measurementId: 'G-MEASUREMENT_ID',
  },
  reCAPTCHAEnterpriseKey: {
    key: "Replace with your recaptcha enterprise site key"
  },
};

מחליפים את הערך של key באסימון של reCaptcha Enterprise.

לאחר מכן, עוברים לקובץ app.config.ts ומוסיפים את הייבוא הבא:

import { getApp } from '@angular/fire/app';
import {
  ReCaptchaEnterpriseProvider,
  initializeAppCheck,
  provideAppCheck,
} from '@angular/fire/app-check';

באותו קובץ app.config.ts, מוסיפים את ההצהרה הבאה על המשתנה הגלובלי:

declare global {
  var FIREBASE_APPCHECK_DEBUG_TOKEN: boolean;
}

@NgModule({ ...

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

imports: [
BrowserModule,
AppRoutingModule,
CommonModule,
FormsModule,
provideFirebaseApp(() => initializeApp(environment.firebase)),
provideAppCheck(() => {
const appCheck = initializeAppCheck(getApp(), {
  provider: new ReCaptchaEnterpriseProvider(
  environment.reCAPTCHAEnterpriseKey.key
  ),
  isTokenAutoRefreshEnabled: true,
  });
  if (location.hostname === 'localhost') {
    self.FIREBASE_APPCHECK_DEBUG_TOKEN = true;
  }
  return appCheck;
}),

כדי לאפשר בדיקה מקומית, מגדירים את self.FIREBASE_APPCHECK_DEBUG_TOKEN כ-true. כשמרעננים את האפליקציה ב-localhost, מתועד אסימון ניפוי באגים במסוף, בדומה לזה:

App Check debug token: CEFC0C76-7891-494B-B764-349BDFD00D00. You will need to add it to your app's App Check settings in the Firebase console for it to work.

עכשיו עוברים אל תצוגת האפליקציות של App Check במסוף Firebase.

לוחצים על תפריט ההוספה ובוחרים באפשרות ניהול אסימוני ניפוי באגים.

לאחר מכן לוחצים על Add debug token (הוספת אסימון ניפוי באגים) ומדביקים את אסימון ניפוי הבאגים מהמסוף לפי ההנחיות.

עוברים לקובץ chat.service.ts ומוסיפים את הייבוא הבא:

import { AppCheck } from '@angular/fire/app-check';

באותו קובץ chat.service.ts, מזינים את App Check לצד שירותי Firebase האחרים.

export class ChatService {
appCheck: AppCheck = inject(AppCheck);
...
  1. יוצרים השמירה עם הודעת השמירה 'חסימת לקוחות לא מורשים באמצעות App Check' ומעבירים אותה למאגר ב-GitHub.
  2. פותחים את הדף App Hosting במסוף Firebase וממתינים להשלמת ההשקה החדשה.

כל הכבוד! עכשיו App Check אמור לפעול באפליקציה.