Cloud Firestore Web Codelab

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

מטרות עסקיות

ב-Codelab זה, תיצרו אפליקציית אינטרנט להמלצות על מסעדות שמבוססת על Cloud Firestore.

img5.png

מה תלמדו

  • קריאת נתונים וכתיבתם ב-Cloud Firestore מאפליקציית אינטרנט
  • האזנה לשינויים בנתונים של Cloud Firestore בזמן אמת
  • שימוש באימות ב-Firebase ובכללי אבטחה כדי לאבטח נתונים ב-Cloud Firestore
  • כתיבת שאילתות מורכבות ב-Cloud Firestore

מה תצטרכו

לפני שמתחילים את ה-codelab הזה, חשוב לוודא שהתקנתם:

  • npm, שבד״כ מגיע עם Node.js – מומלץ להשתמש ב-Node 16 ומעלה
  • סביבת פיתוח משולבת (IDE) או עורך טקסט לפי בחירתכם, כמו WebStorm,‏ VS Code או Sublime

2. יצירה והגדרה של פרויקט Firebase

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

  1. נכנסים למסוף Firebase באמצעות חשבון Google.
  2. לוחצים על הלחצן כדי ליצור פרויקט חדש, ואז מזינים שם לפרויקט (לדוגמה, FriendlyEats).
  3. לוחצים על המשך.
  4. אם מוצגת בקשה לעשות זאת, קוראים ומאשרים את התנאים של Firebase, ואז לוחצים על המשך.
  5. (אופציונלי) מפעילים את העזרה מבוססת-AI במסוף Firebase (שנקראת Gemini ב-Firebase).
  6. ב-codelab הזה לא צריך להשתמש ב-Google Analytics, ולכן משביתים את האפשרות Google Analytics.
  7. לוחצים על יצירת פרויקט, מחכים שהפרויקט יוקצה ולוחצים על המשך.

הגדרת מוצרי Firebase

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

  • אימות ב-Firebase כדי לזהות את המשתמשים בקלות
  • Cloud Firestore כדי לשמור נתונים מובנים בענן ולקבל התראה מיידית כשהנתונים מתעדכנים
  • אירוח ב-Firebase לאירוח ולשליפה של נכסים סטטיים

ב-Codelab הספציפי הזה, כבר הגדרנו את אירוח ב-Firebase. עם זאת, כדי להגדיר את Firebase Auth ו-Cloud Firestore ולהפעיל את השירותים האלה, נסביר לכם איך לעשות את זה באמצעות מסוף Firebase.

הפעלת אימות אנונימי

למרות שהאימות הוא לא הנושא העיקרי של ה-codelab הזה, חשוב שיהיה באפליקציה שלנו סוג כלשהו של אימות. נשתמש בכניסה אנונימית – כלומר, המשתמש ייכנס לחשבון באופן שקט בלי לקבל הנחיה.

צריך להפעיל את האפשרות כניסה אנונימית.

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

img7.png

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

הפעלת Cloud Firestore

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

צריך להפעיל את Cloud Firestore. בקטע Build (פיתוח) במסוף Firebase, לוחצים על Firestore Database (מסד נתונים של Firestore). לוחצים על יצירת מסד נתונים בחלונית Cloud Firestore.

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

rules_version = '2';
service cloud.firestore {

  // Determine if the value of the field "key" is the same
  // before and after the request.
  function unchanged(key) {
    return (key in resource.data)
      && (key in request.resource.data)
      && (resource.data[key] == request.resource.data[key]);
  }

  match /databases/{database}/documents {
    // Restaurants:
    //   - Authenticated user can read
    //   - Authenticated user can create/update (for demo purposes only)
    //   - Updates are allowed if no fields are added and name is unchanged
    //   - Deletes are not allowed (default)
    match /restaurants/{restaurantId} {
      allow read: if request.auth != null;
      allow create: if request.auth != null;
      allow update: if request.auth != null
                    && (request.resource.data.keys() == resource.data.keys())
                    && unchanged("name");

      // Ratings:
      //   - Authenticated user can read
      //   - Authenticated user can create if userId matches
      //   - Deletes and updates are not allowed (default)
      match /ratings/{ratingId} {
        allow read: if request.auth != null;
        allow create: if request.auth != null
                      && request.resource.data.userId == request.auth.uid;
      }
    }
  }
}

בהמשך ה-codelab נסביר על הכללים האלה ואיך הם פועלים.

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

משכפלים את המאגר ב-GitHub משורת הפקודה:

git clone https://github.com/firebase/friendlyeats-web

קוד לדוגמה היה אמור להיות משוכפל לספרייה 📁friendlyeats-web. מעכשיו, חשוב להריץ את כל הפקודות מהספרייה הזו:

cd friendlyeats-web/vanilla-js

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

באמצעות סביבת הפיתוח המשולבת (IDE) (WebStorm,‏ Atom,‏ Sublime,‏ Visual Studio Code וכו'), פותחים או מייבאים את הספרייה 📁friendlyeats-web. הספרייה הזו מכילה את קוד ההתחלה של ה-codelab, שכולל אפליקציה להמלצות על מסעדות שעדיין לא פועלת. במהלך ה-codelab נגרום לה לפעול, ולכן בקרוב תצטרכו לערוך את הקוד בספרייה הזו.

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

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

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

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

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

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

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

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

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

5. הפעלת השרת המקומי

עכשיו אפשר להתחיל לעבוד על האפליקציה. עכשיו נריץ את האפליקציה באופן מקומי.

  1. מריצים את הפקודה הבאה ב-Firebase CLI:
firebase emulators:start --only hosting
  1. שורת הפקודה אמורה להציג את התגובה הבאה:
hosting: Local server: http://localhost:5000

אנחנו משתמשים באמולטור של אירוח ב-Firebase כדי להפעיל את האפליקציה שלנו באופן מקומי. אפליקציית האינטרנט אמורה להיות זמינה עכשיו בכתובת http://localhost:5000.

  1. פותחים את האפליקציה בכתובת http://localhost:5000.

אמורה להופיע העותק של FriendlyEats שמקושר לפרויקט Firebase.

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

img2.png

6. כתיבת נתונים ל-Cloud Firestore

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

מודל נתונים

נתוני Firestore מחולקים לאוספים, למסמכים, לשדות ולאוספי משנה. כל מסעדה תישמר כמסמך באוסף ברמה העליונה שנקרא restaurants.

img3.png

בהמשך, כל ביקורת תישמר בתת-אוסף שנקרא ratings מתחת לכל מסעדה.

img4.png

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

אובייקט המודל הראשי באפליקציה שלנו הוא מסעדה. בואו נכתוב קוד שמוסיף מסמך של מסעדה לאוסף restaurants.

  1. פותחים את הקובץ scripts/FriendlyEats.Data.js שהורד.
  2. מאתרים את הפונקציה FriendlyEats.prototype.addRestaurant.
  3. מחליפים את כל הפונקציה בקוד הבא.

FriendlyEats.Data.js

FriendlyEats.prototype.addRestaurant = function(data) {
  var collection = firebase.firestore().collection('restaurants');
  return collection.add(data);
};

הקוד שלמעלה מוסיף מסמך חדש לאוסף restaurants. נתוני המסמך מגיעים מאובייקט JavaScript פשוט. כדי לעשות את זה, קודם מקבלים הפניה לאוסף Cloud Firestore restaurants ואז add את הנתונים.

שנוסיף מסעדות?

  1. חוזרים לאפליקציית FriendlyEats בדפדפן ומרעננים אותה.
  2. לוחצים על הוספת נתונים לדוגמה.

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

אם תעברו אל הכרטיסייה Cloud Firestore במסוף Firebase, תוכלו לראות מסמכים חדשים באוסף restaurants.

img6.png

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

בקטע הבא נסביר איך לאחזר נתונים מ-Cloud Firestore ולהציג אותם באפליקציה.

7. הצגת נתונים מ-Cloud Firestore

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

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

  1. חוזרים לקובץ scripts/FriendlyEats.Data.js.
  2. מאתרים את הפונקציה FriendlyEats.prototype.getAllRestaurants.
  3. מחליפים את כל הפונקציה בקוד הבא.

FriendlyEats.Data.js

FriendlyEats.prototype.getAllRestaurants = function(renderer) {
  var query = firebase.firestore()
      .collection('restaurants')
      .orderBy('avgRating', 'desc')
      .limit(50);

  this.getDocumentsInQuery(query, renderer);
};

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

כדי לעשות את זה, נוסיף snapshot listener.

  1. חוזרים לקובץ scripts/FriendlyEats.Data.js.
  2. מאתרים את הפונקציה FriendlyEats.prototype.getDocumentsInQuery.
  3. מחליפים את כל הפונקציה בקוד הבא.

FriendlyEats.Data.js

FriendlyEats.prototype.getDocumentsInQuery = function(query, renderer) {
  query.onSnapshot(function(snapshot) {
    if (!snapshot.size) return renderer.empty(); // Display "There are no restaurants".

    snapshot.docChanges().forEach(function(change) {
      if (change.type === 'removed') {
        renderer.remove(change.doc);
      } else {
        renderer.display(change.doc);
      }
    });
  });
};

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

  • בפעם הראשונה, הקריאה החוזרת מופעלת עם כל קבוצת התוצאות של השאילתה – כלומר, כל restaurants האוסף מ-Cloud Firestore. לאחר מכן, הפונקציה renderer.display מקבלת את כל המסמכים בנפרד.
  • כשמסמך נמחק, change.type שווה ל-removed. לכן במקרה הזה, נקרא לפונקציה שמסירה את המסעדה מממשק המשתמש.

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

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

img5.png

8. נתוני Get()

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

כדאי להטמיע שיטה שמופעלת כשמשתמש לוחץ על מסעדה ספציפית באפליקציה.

  1. חוזרים לקובץ scripts/FriendlyEats.Data.js.
  2. מאתרים את הפונקציה FriendlyEats.prototype.getRestaurant.
  3. מחליפים את כל הפונקציה בקוד הבא.

FriendlyEats.Data.js

FriendlyEats.prototype.getRestaurant = function(id) {
  return firebase.firestore().collection('restaurants').doc(id).get();
};

אחרי שמטמיעים את השיטה הזו, אפשר לראות דפים לכל מסעדה. פשוט לוחצים על מסעדה ברשימה ומוצג דף הפרטים של המסעדה:

img1.png

בשלב הזה, אי אפשר להוסיף דירוגים, אבל בהמשך נטמיע את האפשרות הזו ב-codelab.

9. מיון וסינון של נתונים

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

הנה דוגמה לשאילתה פשוטה לאחזור כל המסעדות Dim Sum:

var filteredQuery = query.where('category', '==', 'Dim Sum')

כפי שהשם מרמז, השיטה where() תגרום לכך שהשאילתה תוריד רק את החברים באוסף שהשדות שלהם עומדים בהגבלות שהגדרנו. במקרה כזה, יורדו רק מסעדות שבהן category הוא Dim Sum.

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

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

  1. חוזרים לקובץ scripts/FriendlyEats.Data.js.
  2. מאתרים את הפונקציה FriendlyEats.prototype.getFilteredRestaurants.
  3. מחליפים את כל הפונקציה בקוד הבא.

FriendlyEats.Data.js

FriendlyEats.prototype.getFilteredRestaurants = function(filters, renderer) {
  var query = firebase.firestore().collection('restaurants');

  if (filters.category !== 'Any') {
    query = query.where('category', '==', filters.category);
  }

  if (filters.city !== 'Any') {
    query = query.where('city', '==', filters.city);
  }

  if (filters.price !== 'Any') {
    query = query.where('price', '==', filters.price.length);
  }

  if (filters.sort === 'Rating') {
    query = query.orderBy('avgRating', 'desc');
  } else if (filters.sort === 'Reviews') {
    query = query.orderBy('numRatings', 'desc');
  }

  this.getDocumentsInQuery(query, renderer);
};

הקוד שלמעלה מוסיף כמה מסננים where וסעיף orderBy אחד כדי ליצור שאילתה מורכבת על סמך קלט של משתמשים. השאילתה תחזיר עכשיו רק מסעדות שתואמות לדרישות של המשתמש.

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

The query requires an index. You can create it here: https://console.firebase.google.com/project/project-id/database/firestore/indexes?create_composite=...

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

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

10. פריסת אינדקסים

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

  1. בספרייה המקומית שהורדתם של האפליקציה, יופיע קובץ firestore.indexes.json.

בקובץ הזה מתוארים כל האינדקסים שנדרשים לכל השילובים האפשריים של מסננים.

firestore.indexes.json

{
 "indexes": [
   {
     "collectionGroup": "restaurants",
     "queryScope": "COLLECTION",
     "fields": [
       { "fieldPath": "city", "order": "ASCENDING" },
       { "fieldPath": "avgRating", "order": "DESCENDING" }
     ]
   },

   ...

 ]
}
  1. מפעילים את הפקודה הבאה כדי לפרוס את האינדקסים האלה:
firebase deploy --only firestore:indexes

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

11. כתיבת נתונים בעסקה

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

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

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

  1. חוזרים לקובץ scripts/FriendlyEats.Data.js.
  2. מאתרים את הפונקציה FriendlyEats.prototype.addRating.
  3. מחליפים את כל הפונקציה בקוד הבא.

FriendlyEats.Data.js

FriendlyEats.prototype.addRating = function(restaurantID, rating) {
  var collection = firebase.firestore().collection('restaurants');
  var document = collection.doc(restaurantID);
  var newRatingDocument = document.collection('ratings').doc();

  return firebase.firestore().runTransaction(function(transaction) {
    return transaction.get(document).then(function(doc) {
      var data = doc.data();

      var newAverage =
          (data.numRatings * data.avgRating + rating.rating) /
          (data.numRatings + 1);

      transaction.update(document, {
        numRatings: data.numRatings + 1,
        avgRating: newAverage
      });
      return transaction.set(newRatingDocument, rating);
    });
  });
};

בבלוק שלמעלה, מופעלת טרנזקציה לעדכון הערכים המספריים של avgRating ו-numRatings במסמך של המסעדה. במקביל, אנחנו מוסיפים את rating החדש לאוסף המשנה ratings.

12. אבטחת הנתונים

בתחילת ה-codelab הזה, הגדרנו את כללי האבטחה של האפליקציה כדי להגביל את הגישה לאפליקציה.

firestore.rules

rules_version = '2';
service cloud.firestore {

  // Determine if the value of the field "key" is the same
  // before and after the request.
  function unchanged(key) {
    return (key in resource.data)
      && (key in request.resource.data)
      && (resource.data[key] == request.resource.data[key]);
  }

  match /databases/{database}/documents {
    // Restaurants:
    //   - Authenticated user can read
    //   - Authenticated user can create/update (for demo purposes only)
    //   - Updates are allowed if no fields are added and name is unchanged
    //   - Deletes are not allowed (default)
    match /restaurants/{restaurantId} {
      allow read: if request.auth != null;
      allow create: if request.auth != null;
      allow update: if request.auth != null
                    && (request.resource.data.keys() == resource.data.keys())
                    && unchanged("name");

      // Ratings:
      //   - Authenticated user can read
      //   - Authenticated user can create if userId matches
      //   - Deletes and updates are not allowed (default)
      match /ratings/{ratingId} {
        allow read: if request.auth != null;
        allow create: if request.auth != null
                      && request.resource.data.userId == request.auth.uid;
      }
    }
  }
}

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

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

במקום להשתמש במסוף Firebase, אפשר להשתמש ב-Firebase CLI כדי לפרוס כללים לפרויקט Firebase. הקובץ firestore.rules בספריית העבודה כבר מכיל את הכללים שלמעלה. כדי לפרוס את הכללים האלה ממערכת הקבצים המקומית (במקום להשתמש במסוף Firebase), מריצים את הפקודה הבאה:

firebase deploy --only firestore:rules

13. סיכום

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

מידע נוסף על Cloud Firestore זמין במקורות המידע הבאים:

14. [אופציונלי] אכיפה באמצעות App Check

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

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

הפעלת reCAPTCHA Enterprise

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

הפעלת App Check

  1. במסוף Firebase, מאתרים את הקטע Build בחלונית הימנית.
  2. לוחצים על App Check ואז על הלחצן Get Started (או מועברים ישירות אל המסוף).
  3. לוחצים על הרשמה, מזינים את המפתח של reCAPTCHA Enterprise כשמופיעה בקשה ולוחצים על שמירה.
  4. בתצוגת ה-API, בוחרים באפשרות אחסון ולוחצים על החלה. חוזרים על הפעולה עבור Cloud Firestore.

האכיפה של App Check אמורה להתבצע עכשיו. רעננו את האפליקציה ונסו ליצור מסעדה או לצפות בה. אמורה להופיע הודעת השגיאה:

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

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

עוברים לקובץ FriendlyEats.View.js, מעדכנים את הפונקציה initAppCheck ומוסיפים את מפתח reCAPTCHA כדי לאתחל את App Check.

FriendlyEats.prototype.initAppCheck = function() {
    var appCheck = firebase.appCheck();
    appCheck.activate(
    new firebase.appCheck.ReCaptchaEnterpriseProvider(
      /* reCAPTCHA Enterprise site key */
    ),
    true // Set to true to allow auto-refresh.
  );
};

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

כדי להפעיל בדיקה מקומית, מחפשים את הקטע שבו האפליקציה מאותחלת בקובץ FriendlyEats.js ומוסיפים את השורה הבאה לפונקציה FriendlyEats.prototype.initAppCheck:

if(isLocalhost) {
  self.FIREBASE_APPCHECK_DEBUG_TOKEN = true;
}

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

App Check debug token: 8DBDF614-649D-4D22-B0A3-6D489412838B. You will need to add it to your app's App Check settings in the Firebase console for it to work.

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

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

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

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