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

מטרות

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

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

תנאים מוקדמים

לפני שתתחיל ב- codelab זה וודא שיש לך:

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

9d2f625aebcab6af.png

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

הורד את הקוד

הפעל את הפקודה הבאה כדי לשכפל את קוד הדוגמה עבור קוד קוד זה. פעולה זו תיצור תיקייה בשם 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/ התיקייה של קוד מדגם. לאחר מכן לחץ על הבא.

בשנת 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 .

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

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

בטרמינל שלך מתוך 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.

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

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

פתח את הקובץ 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

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

de06424023ffb4b9.png

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

בחלק זה נכתוב כמה נתונים ל- 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

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

מזל טוב, כתבת רק נתונים ל- 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

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

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

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

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

אוספים ואוספי משנה

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

עד כה לא שקלנו את האבטחה של יישום זה. כיצד נדע שמשתמשים יכולים לקרוא ולכתוב רק את הנתונים הנכונים? 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;
      }
    }
  }
}

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

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

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

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

למד עוד

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

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

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

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

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

אימות Firebase

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

הפעל את שיטת הכניסה לדוא"ל:

334ef7f6ff4da4ce.png

חנות האש

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

נווט אל המקטע 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 ולהפעיל את היישום שוב.

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