Codelab אנדרואיד של Cloud Firestore

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

מטרות

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

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

דרישות מוקדמות

לפני שתתחיל מעבדת קוד זה ודא שיש לך:

  • 4.0 ומעלה סטודיו אנדרואיד
  • אמולטור אנדרואיד
  • גרסת Node.js 10 ומעלה
  • Java גרסה 8 ומעלה

2. צור פרויקט Firebase

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

9d2f625aebcab6af.png

  1. ייתכן שתתבקש להפעיל את Google Analytics, למטרות מעבדת קוד זה הבחירה שלך לא משנה.
  2. לאחר כדקה, פרויקט Firebase שלך ​​יהיה מוכן. לחץ על המשך.

3. הגדר את הפרויקט לדוגמה

הורד את הקוד

הפעל את הפקודה הבאה כדי לשכפל את הקוד לדוגמה עבור מעבדת קוד זה. פעולה זו תיצור תיקייה בשם friendlyeats-android במחשב שלך:

$ git clone https://github.com/firebase/friendlyeats-android

אם אין לך git במחשב שלך, אתה יכול גם להוריד את הקוד ישירות מ-GitHub.

לייבא את הפרוייקט סטודיו אנדרואיד. אתה בטח תראה כמה שגיאות הידור או אולי אזהרה לגבי חסר google-services.json קובץ. נתקן זאת בסעיף הבא.

הוסף תצורת Firebase

  1. בשנות ה קונסולת Firebase , בחר סקירת פרויקט בניווט הימני. לחץ על לחצן אנדרואיד לבחור בפלטפורמה. כשתתבקש השימוש בשם חבילה com.google.firebase.example.fireeats

73d151ed16016421.png

  1. לחץ לרשום את האפליקציה ופעל בהתאם להוראות כדי להוריד את google-services.json קובץ, ולהעביר אותו לתוך app/ התיקייה של קוד מדגם. לאחר מכן לחץ על הבא.

4. הגדר את אמולטורי Firebase

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

התקן את Firebase CLI

ראשית תצטרך להתקין את Firebase CLI . הדרך הקלה ביותר לעשות זאת היא להשתמש npm :

npm install -g firebase-tools

אם אין לך npm או נתקל בשגיאה, לקרוא את הוראות ההתקנה כדי לקבל בינארי עצמאי לפלטפורמה שלך.

לאחר שהתקנת את CLI, ריצת firebase --version צריכה לדווח גרסה של 9.0.0 ומעלה:

$ firebase --version
9.0.0

התחברות

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

מ בתוך friendlyeats-android בטווח תיקייה firebase use --add להתחבר הפרויקט המקומי לפרויקט Firebase שלך. פעל לפי ההנחיות לבחירת הפרויקט שיצרת קודם ואם אתה מתבקש לבחור כינוי להיכנס default .

5. הפעל את האפליקציה

עכשיו הגיע הזמן להפעיל את Firebase Emulator Suite ואת אפליקציית FriendlyEats Android בפעם הראשונה.

הפעל את האמולטורים

בטרמינל שלך מתוך friendlyeats-android בטווח ספרייה firebase emulators:start להתחיל את אמולטורים Firebase. אתה אמור לראות יומנים כמו זה:

$ firebase emulators:start
i  emulators: Starting emulators: auth, firestore
i  firestore: Firestore Emulator logging to firestore-debug.log
i  ui: Emulator UI logging to ui-debug.log

┌─────────────────────────────────────────────────────────────┐
│ ✔  All emulators ready! It is now safe to connect your app. │
│ i  View Emulator UI at http://localhost:4000                │
└─────────────────────────────────────────────────────────────┘

┌────────────────┬────────────────┬─────────────────────────────────┐
│ Emulator       │ Host:Port      │ View in Emulator UI             │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Authentication │ localhost:9099 │ http://localhost:4000/auth      │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Firestore      │ localhost:8080 │ http://localhost:4000/firestore │
└────────────────┴────────────────┴─────────────────────────────────┘
  Emulator Hub running at localhost:4400
  Other reserved ports: 4500

Issues? Report them at https://github.com/firebase/firebase-tools/issues and attach the *-debug.log files.

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

חבר את האפליקציה לאמולטורים

פתח את הקובץ FirebaseUtil.java בסטודיו אנדרואיד. קובץ זה מכיל את ההיגיון לחיבור ה-SDKs של Firebase לאמולטורים המקומיים הפועלים במחשב שלך.

בחלק העליון של הקובץ, בדוק את השורה הזו:

    /** Use emulators only in debug builds **/
    private static final boolean sUseEmulators = BuildConfig.DEBUG;

אנחנו משתמשים BuildConfig לוודא שאנחנו רק להתחבר אמולטורים כאשר האפליקציה שלנו פועלת debug מצב. כשאנו לקמפל את האפליקציה ב release מצב מצב זה יהיה שקר.

עכשיו תסתכל על getFirestore() שיטה:

    public static FirebaseFirestore getFirestore() {
        if (FIRESTORE == null) {
            FIRESTORE = FirebaseFirestore.getInstance();

            // Connect to the Cloud Firestore emulator when appropriate. The host '10.0.2.2' is a
            // special IP address to let the Android emulator connect to 'localhost'.
            if (sUseEmulators) {
                FIRESTORE.useEmulator("10.0.2.2", 8080);
            }
        }

        return FIRESTORE;
    }

אנו יכולים לראות כי היא באמצעות useEmulator(host, port) שיטה לחבר את Firebase SDK האמולטור Firestore המקומי. בכל היישום נשתמש FirebaseUtil.getFirestore() כדי לגשת במקרה זה של FirebaseFirestore ולכן אנחנו בטוחים שאנחנו תמיד מנסים להתחבר אמולטור Firestore כאשר רץ debug מצב.

הפעל את האפליקציה

אם יש לך להוסיף את google-services.json הקובץ כראוי, הפרויקט צריך ללקט. בשנת Build לחץ סטודיו אנדרואיד> Rebuild פרויקט ולוודא שאין שגיאות נותרות.

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

עכשיו לפתוח את אמולטורים UI ידי ניווט אל http: // localhost: 4000 בדפדפן האינטרנט שלך. לאחר מכן לחץ על כרטיסיית האימות ואתה צריך לראות את החשבון שיצרת רגע:

Firebase Auth Emulator

לאחר השלמת תהליך הכניסה, אתה אמור לראות את מסך הבית של האפליקציה:

de06424023ffb4b9.png

בקרוב נוסיף כמה נתונים כדי לאכלס את מסך הבית.

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

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

מטרת המודל העיקרית ביישום שלנו היא מסעדה (ראה model/Restaurant.java ). נתוני Firestore מפוצלים למסמכים, אוספים ותתי-אוספים. אנו נאחסן כל מסעדה כמסמך באוסף ברמה העליונה בשם "restaurants" . כדי ללמוד עוד על מודל הנתונים Firestore, לקרוא על מסמכים ואוספים ב בתיעוד .

למטרות הדגמה, נוסיף פונקציונליות באפליקציה ליצירת עשר מסעדות אקראיות כאשר נלחץ על כפתור "הוסף פריטים אקראיים" בתפריט ההצפה. פתח את הקובץ MainActivity.java ומלא את onAddItemsClicked() שיטה:

    private void onAddItemsClicked() {
        // Get a reference to the restaurants collection
        CollectionReference restaurants = mFirestore.collection("restaurants");

        for (int i = 0; i < 10; i++) {
            // Get a random Restaurant POJO
            Restaurant restaurant = RestaurantUtil.getRandom(this);

            // Add a new document to the restaurants collection
            restaurants.add(restaurant);
        }
    }

יש כמה דברים חשובים שיש לשים לב לקוד למעלה:

  • התחלנו לקבל התייחסות "restaurants" האוסף. אוספים נוצרים באופן מרומז כאשר מוסיפים מסמכים, כך שלא היה צורך ליצור את האוסף לפני כתיבת נתונים.
  • ניתן ליצור מסמכים באמצעות POJOs, שבהם אנו משתמשים כדי ליצור כל מסמך מסעדה.
  • add() שיטה מוסיף מסמך אוסף עם מזהה שנוצר באופן אוטומטי, כך שאנחנו לא צריכים לציין מזהה ייחודי עבור כל מסעדה.

כעת הפעל את האפליקציה שוב ולחץ על כפתור "הוסף פריטים אקראיים" בתפריט הגלישה כדי להפעיל את הקוד שזה עתה כתבת:

95691e9b71ba55e3.png

עכשיו לפתוח את אמולטורים UI ידי ניווט אל http: // localhost: 4000 בדפדפן האינטרנט שלך. לאחר מכן לחץ על הכרטיסייה Firestore ואתה צריך לראות את הנתונים שהוספת זה עתה:

Firebase Auth Emulator

נתונים אלה הם 100% מקומיים למחשב שלך. למעשה, הפרויקט האמיתי שלך אפילו לא מכיל מסד נתונים של Firestore עדיין! משמעות הדבר היא שבטוח להתנסות בשינוי ומחיקה של נתונים אלה ללא השלכות.

מזל טוב, זה עתה כתבת נתונים ל-Firestore! בשלב הבא נלמד כיצד להציג נתונים אלו באפליקציה.

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

בשלב זה נלמד כיצד לאחזר נתונים מ-Firestore ולהציג אותם באפליקציה שלנו. הצעד הראשון כדי קריאת נתונים מתוך Firestore הוא ליצור Query . שנה את onCreate() שיטה:

        mFirestore = FirebaseUtil.getFirestore();

        // Get the 50 highest rated restaurants
        mQuery = mFirestore.collection("restaurants")
                .orderBy("avgRating", Query.Direction.DESCENDING)
                .limit(LIMIT);

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

פתח את FirestoreAdapter בכיתה, אשר יושמה באופן חלקי כבר. ראשית, בואו נעשינו את המתאם ליישם EventListener ולהגדיר את onEvent הפונקציה כך שהוא יכול לקבל עדכונים לשאילתא Firestore:

public abstract class FirestoreAdapter<VH extends RecyclerView.ViewHolder>
        extends RecyclerView.Adapter<VH>
        implements EventListener<QuerySnapshot> { // Add this "implements"

    // ...

    // Add this method
    @Override
    public void onEvent(QuerySnapshot documentSnapshots,
                        FirebaseFirestoreException e) {

        // Handle errors
        if (e != null) {
            Log.w(TAG, "onEvent:error", e);
            return;
        }

        // Dispatch the event
        for (DocumentChange change : documentSnapshots.getDocumentChanges()) {
            // Snapshot of the changed document
            DocumentSnapshot snapshot = change.getDocument();

            switch (change.getType()) {
                case ADDED:
                    // TODO: handle document added
                    break;
                case MODIFIED:
                    // TODO: handle document modified
                    break;
                case REMOVED:
                    // TODO: handle document removed
                    break;
            }
        }

        onDataChanged();
    }

  // ...
}

בטעינה הראשונית המאזין יקבל אחד ADDED אירוע עבור כל מסמך חדש. כאשר מערך התוצאות של השאילתה משתנה עם הזמן המאזין יקבל יותר אירועים המכילים את השינויים. כעת נסיים ליישם את המאזין. ראשית להוסיף שלוש שיטות חדשות: onDocumentAdded , onDocumentModified , ועל onDocumentRemoved :

    protected void onDocumentAdded(DocumentChange change) {
        mSnapshots.add(change.getNewIndex(), change.getDocument());
        notifyItemInserted(change.getNewIndex());
    }

    protected void onDocumentModified(DocumentChange change) {
        if (change.getOldIndex() == change.getNewIndex()) {
            // Item changed but remained in same position
            mSnapshots.set(change.getOldIndex(), change.getDocument());
            notifyItemChanged(change.getOldIndex());
        } else {
            // Item changed and changed position
            mSnapshots.remove(change.getOldIndex());
            mSnapshots.add(change.getNewIndex(), change.getDocument());
            notifyItemMoved(change.getOldIndex(), change.getNewIndex());
        }
    }

    protected void onDocumentRemoved(DocumentChange change) {
        mSnapshots.remove(change.getOldIndex());
        notifyItemRemoved(change.getOldIndex());
    }

ואז קוראים שיטות חדשות אלו onEvent :

    @Override
    public void onEvent(QuerySnapshot documentSnapshots,
                        FirebaseFirestoreException e) {

        // ...

        // Dispatch the event
        for (DocumentChange change : documentSnapshots.getDocumentChanges()) {
            // Snapshot of the changed document
            DocumentSnapshot snapshot = change.getDocument();

            switch (change.getType()) {
                case ADDED:
                    onDocumentAdded(change); // Add this line
                    break;
                case MODIFIED:
                    onDocumentModified(change); // Add this line
                    break;
                case REMOVED:
                    onDocumentRemoved(change); // Add this line
                    break;
            }
        }

        onDataChanged();
    }

לבסוף ליישם את startListening() שיטה לצרף את המאזין:

    public void startListening() {
        if (mQuery != null && mRegistration == null) {
            mRegistration = mQuery.addSnapshotListener(this);
        }
    }

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

9e45f40faefce5d0.png

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

8. מיין וסנן נתונים

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

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

67898572a35672a5.png

בואו לערוך את onFilter() שיטה של MainActivity.java . שיטה זו מקבלת Filters אובייקט המהווה אובייקט עוזר יצרנו כדי ללכוד את הפלט של השיח המסנן. נשנה שיטה זו כדי לבנות שאילתה מהמסננים:

    @Override
    public void onFilter(Filters filters) {
        // Construct query basic query
        Query query = mFirestore.collection("restaurants");

        // Category (equality filter)
        if (filters.hasCategory()) {
            query = query.whereEqualTo("category", filters.getCategory());
        }

        // City (equality filter)
        if (filters.hasCity()) {
            query = query.whereEqualTo("city", filters.getCity());
        }

        // Price (equality filter)
        if (filters.hasPrice()) {
            query = query.whereEqualTo("price", filters.getPrice());
        }

        // Sort by (orderBy with direction)
        if (filters.hasSortBy()) {
            query = query.orderBy(filters.getSortBy(), filters.getSortDirection());
        }

        // Limit items
        query = query.limit(LIMIT);

        // Update the query
        mQuery = query;
        mAdapter.setQuery(query);

        // Set header
        mCurrentSearchView.setText(Html.fromHtml(filters.getSearchDescription(this)));
        mCurrentSortByView.setText(filters.getOrderDescription(this));

        // Save filters
        mViewModel.setFilters(filters);
    }

בשנת הקוד שלעיל אנו בונים Query אובייקט על ידי הצמדת where ו orderBy סעיפים להתאים את המסננים נתון.

הפעל את היישום שוב ובחר את המסנן הבא כדי להראות המסעדות במחיר נמוך הפופולריות ביותר:

7a67a8a400c80c50.png

כעת אתה אמור לראות רשימה מסוננת של מסעדות המכילה רק אפשרויות במחיר נמוך:

a670188398c3c59.png

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

9. ארגן נתונים בתתי אוספים

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

אוספים ותתי אוספים

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

כדי לגשת subcollection, שיחת .collection() על מסמך הורה:

CollectionReference subRef = mFirestore.collection("restaurants")
        .document("abc123")
        .collection("ratings");

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

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

הוספת Rating ל subcollection נכונה רק דורש קורא .add() , אבל אנחנו גם צריכים לעדכן את Restaurant הדירוג הממוצע של האובייקט מספר הדירוגים כדי לשקף את הנתונים החדשים. אם נשתמש בפעולות נפרדות כדי לבצע את שני השינויים הללו, ישנם מספר תנאי מרוץ שעלולים לגרום לנתונים מעודכנים או שגויים.

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

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

Open RestaurantDetailActivity.java וליישם את addRating פונקציה:

    private Task<Void> addRating(final DocumentReference restaurantRef,
                                 final Rating rating) {
        // Create reference for new rating, for use inside the transaction
        final DocumentReference ratingRef = restaurantRef.collection("ratings")
                .document();

        // In a transaction, add the new rating and update the aggregate totals
        return mFirestore.runTransaction(new Transaction.Function<Void>() {
            @Override
            public Void apply(Transaction transaction)
                    throws FirebaseFirestoreException {

                Restaurant restaurant = transaction.get(restaurantRef)
                        .toObject(Restaurant.class);

                // Compute new number of ratings
                int newNumRatings = restaurant.getNumRatings() + 1;

                // Compute new average rating
                double oldRatingTotal = restaurant.getAvgRating() *
                        restaurant.getNumRatings();
                double newAvgRating = (oldRatingTotal + rating.getRating()) /
                        newNumRatings;

                // Set new restaurant info
                restaurant.setNumRatings(newNumRatings);
                restaurant.setAvgRating(newAvgRating);

                // Commit to Firestore
                transaction.set(restaurantRef, restaurant);
                transaction.set(ratingRef, rating);

                return null;
            }
        });
    }

addRating() הפונקציה מחזירה Task המייצג את העסקה כולה. בשנות ה onRating() מאזינים פונקציה מתווספים משימה להגיב לתוצאות העסקה.

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

78fa16cdf8ef435a.png

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

f9e670f40bd615b0.png

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

10. אבטח את הנתונים שלך

עד כה לא שקלנו את האבטחה של יישום זה. איך נדע שמשתמשים יכולים לקרוא ולכתוב רק את הנתונים הנכונים? Firestore datbases מובטחת קובץ תצורה הנקרא כלל אבטחה .

פתח את firestore.rules הקובץ, אתה צריך לראות את הדברים הבאים:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      //
      // WARNING: These rules are insecure! We will replace them with
      // more secure rules later in the codelab
      //
      allow read, write: if request.auth != null;
    }
  }
}

השינוי באים כללים אלה כדי למנוע נתונים רצוי acesss או שינויים, לפתוח את firestore.rules הקובץ ולהחליף את התוכן עם הבאים:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Determine if the value of the field "key" is the same
    // before and after the request.
    function isUnchanged(key) {
      return (key in resource.data)
        && (key in request.resource.data)
        && (resource.data[key] == request.resource.data[key]);
    }

    // Restaurants
    match /restaurants/{restaurantId} {
      // Any signed-in user can read
      allow read: if request.auth != null;

      // Any signed-in user can create
      // WARNING: this rule is for demo purposes only!
      allow create: if request.auth != null;

      // Updates are allowed if no fields are added and name is unchanged
      allow update: if request.auth != null
                    && (request.resource.data.keys() == resource.data.keys())
                    && isUnchanged("name");

      // Deletes are not allowed.
      // Note: this is the default, there is no need to explicitly state this.
      allow delete: if false;

      // Ratings
      match /ratings/{ratingId} {
        // Any signed-in user can read
        allow read: if request.auth != null;

        // Any signed-in user can create if their uid matches the document
        allow create: if request.auth != null
                      && request.resource.data.userId == request.auth.uid;

        // Deletes and updates are not allowed (default)
        allow update, delete: if false;
      }
    }
  }
}

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

כדי לקרוא עוד על כלל אבטחה, לבקר את התיעוד .

11. מסקנה

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

  • מסמכים ואוספים
  • קריאה וכתיבה של נתונים
  • מיון וסינון באמצעות שאילתות
  • אוספי משנה
  • עסקאות

למד עוד

כדי להמשיך ללמוד על Firestore, הנה כמה מקומות טובים להתחיל:

אפליקציית המסעדה במעבדת קוד זה התבססה על האפליקציה לדוגמה "Friendly Eats". ניתן לעיין בקוד המקור לאותה אפליקציה כאן .

אופציונלי: פרוס לייצור

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

12. (אופציונלי) פרוס את האפליקציה שלך

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

אימות Firebase

בשנות ה Firebase consle עברו לסעיף ו לנווט אימות אל סימן-בלשונית ספקי .

הפעל את שיטת הכניסה באימייל:

334ef7f6ff4da4ce.png

Firestore

צור מסד נתונים

נווט אל המקטע Firestore של קונסולת ולחץ על צור מסד נתונים:

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

פריסת כללים

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

$ firebase deploy --only firestore:rules

זה יהיה לפרוס את תוכן firestore.rules לפרויקט שלך, שבו אתה יכול לאשר על ידי ניווט אל הכרטיסייה כללי במסוף.

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

לאפליקציית FriendlyEats יש מיון וסינון מורכבים הדורשים מספר אינדקסים מורכבים מותאמים אישית. אלה יכולים להיווצר על ידי היד של Firebase קונסולת אבל זה פשוט לכתוב ההגדרות שלהם firestore.indexes.json קובץ ולפרוס אותם באמצעות Firebase CLI.

אם אתה פותח את firestore.indexes.json קובץ תוכלו לראות כי המדדים הנדרשים כבר ניתנו:

{
  "indexes": [
    {
      "collectionId": "restaurants",
      "queryScope": "COLLECTION",
      "fields": [
        { "fieldPath": "city", "mode": "ASCENDING" },
        { "fieldPath": "avgRating", "mode": "DESCENDING" }
      ]
    },
    {
      "collectionId": "restaurants",
      "queryScope": "COLLECTION",
      "fields": [
        { "fieldPath": "category", "mode": "ASCENDING" },
        { "fieldPath": "avgRating", "mode": "DESCENDING" }
      ]
    },
    {
      "collectionId": "restaurants",
      "queryScope": "COLLECTION",
      "fields": [
        { "fieldPath": "price", "mode": "ASCENDING" },
        { "fieldPath": "avgRating", "mode": "DESCENDING" }
      ]
    },
    {
      "collectionId": "restaurants",
      "queryScope": "COLLECTION",
      "fields": [
        { "fieldPath": "city", "mode": "ASCENDING" },
        { "fieldPath": "numRatings", "mode": "DESCENDING" }
      ]
    },
    {
      "collectionId": "restaurants",
      "queryScope": "COLLECTION",
      "fields": [
        { "fieldPath": "category", "mode": "ASCENDING" },
        { "fieldPath": "numRatings", "mode": "DESCENDING" }
      ]
    },
    {
      "collectionId": "restaurants",
      "queryScope": "COLLECTION",
      "fields": [
        { "fieldPath": "price", "mode": "ASCENDING" },
        { "fieldPath": "numRatings", "mode": "DESCENDING" }
      ]
    },
    {
      "collectionId": "restaurants",
      "queryScope": "COLLECTION",
      "fields": [
        { "fieldPath": "city", "mode": "ASCENDING" },
        { "fieldPath": "price", "mode": "ASCENDING" }
      ]
    },
    {
      "collectionId": "restaurants",
      "fields": [
        { "fieldPath": "category", "mode": "ASCENDING" },
        { "fieldPath": "price", "mode": "ASCENDING" }
      ]
    }
  ],
  "fieldOverrides": []
}

כדי לפרוס את האינדקסים האלה, הפעל את הפקודה הבאה:

$ firebase deploy --only firestore:indexes

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

הגדר את האפליקציה

בשנות ה FirebaseUtil בכיתה אנו הגדרנו את Firebase SDK כדי להתחבר אמולטורים במצב debug:

public class FirebaseUtil {

    /** Use emulators only in debug builds **/
    private static final boolean sUseEmulators = BuildConfig.DEBUG;

    // ...
}

אם תרצה לבדוק את האפליקציה שלך עם פרויקט Firebase האמיתי שלך, תוכל:

  1. בנה את האפליקציה במצב שחרור והפעל אותה במכשיר.
  2. שנה באופן זמני sUseEmulators כדי false ולהפעיל את היישום שוב.

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