Cloud Firestore Web Codelab

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

מטרות עסקיות

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

ב-codelab הספציפי הזה, כבר הגדרנו את Firebase Hosting. עם זאת, כדי להגדיר את 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 Hosting כדי להפעיל את האפליקציה באופן מקומי. אפליקציית האינטרנט אמורה להיות זמינה עכשיו בכתובת 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 Console ולמחוק ידנית מסעדה או לשנות את השם שלה – השינויים יופיעו באתר שלכם באופן מיידי.

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 (או מועברים ישירות אל console).
  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.

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

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

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