क्लाउड फायरस्टोर एंड्रॉइड कोडलैब

1 अवलोकन

लक्ष्य

इस कोडलैब में आप क्लाउड फायरस्टोर द्वारा समर्थित एंड्रॉइड पर एक रेस्तरां अनुशंसा ऐप का निर्माण करेंगे। आप जान जायेंगे कैसे:

  • किसी Android ऐप से Firestore को डेटा पढ़ें और लिखें
  • रीयलटाइम में Firestore डेटा में बदलाव सुनें
  • Firestore डेटा सुरक्षित करने के लिए Firebase प्रमाणीकरण और सुरक्षा नियमों का उपयोग करें
  • जटिल फायरस्टोर प्रश्न लिखें

आवश्यक शर्तें

इस कोडलैब को शुरू करने से पहले सुनिश्चित करें कि आपके पास:

  • एंड्रॉयड स्टूडियो 4.0 या उच्चतर
  • एक एंड्रॉइड एमुलेटर
  • Node.js संस्करण 10 या उच्चतर
  • जावा संस्करण 8 या उन्नत

2. एक फायरबेस प्रोजेक्ट बनाएं

  1. में प्रवेश करें Firebase सांत्वना अपने Google खाते से।
  2. में Firebase कंसोल , परियोजना जोड़ें क्लिक करें।
  3. नीचे के रूप में स्क्रीन कैप्चर में दिखाया गया है, अपने Firebase परियोजना के लिए एक नाम दर्ज (उदाहरण के लिए, "दोस्ताना" खाती है), और जारी रखें क्लिक करें।

9d2f625aebcab6af.png

  1. आपको Google Analytics को सक्षम करने के लिए कहा जा सकता है, इस कोडलैब के प्रयोजनों के लिए आपका चयन कोई मायने नहीं रखता।
  2. एक-एक मिनट के बाद, आपका फायरबेस प्रोजेक्ट तैयार हो जाएगा। जारी रखें पर क्लिक करें।

3. नमूना परियोजना सेट करें

कोड डाउनलोड करें

इस कोडलैब के लिए नमूना कोड को क्लोन करने के लिए निम्न कमांड चलाएँ। यह नामक फ़ोल्डर पैदा करेगा friendlyeats-android आपकी मशीन पर:

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

यदि आपकी मशीन पर git नहीं है, तो आप सीधे GitHub से भी कोड डाउनलोड कर सकते हैं।

एंड्रॉयड स्टूडियो में परियोजना आयात करें। आप शायद कुछ संकलन त्रुटियों या शायद एक लापता के बारे में एक चेतावनी दिखाई देगी google-services.json फ़ाइल। हम इसे अगले भाग में ठीक करेंगे।

फायरबेस कॉन्फ़िगरेशन जोड़ें

  1. में Firebase कंसोल , बाएं नेविगेशन में परियोजना अवलोकन का चयन करें। मंच का चयन करने के एंड्रॉयड बटन क्लिक करें। एक पैकेज नाम उपयोग के लिए संकेत देने com.google.firebase.example.fireeats

73d151ed16016421.png

  1. रजिस्टर अनुप्रयोग पर क्लिक करें और डाउनलोड करने के लिए निर्देशों का पालन करें google-services.json फ़ाइल, और यह में कदम app/ नमूना कोड का फ़ोल्डर। फिर अगला क्लिक करें।

4. फायरबेस एमुलेटर सेट करें

इस codelab में आप इस्तेमाल करेंगे Firebase एम्यूलेटर सुइट स्थानीय रूप से बादल Firestore और अन्य Firebase सेवाओं का अनुकरण करने की। यह आपके ऐप को बनाने के लिए एक सुरक्षित, तेज़ और मुफ़्त स्थानीय विकास परिवेश प्रदान करता है।

फायरबेस सीएलआई स्थापित करें

सबसे पहले आप को स्थापित करना होगा Firebase CLI । यह करने के लिए सबसे आसान तरीका उपयोग करने के लिए है npm :

npm install -g firebase-tools

आप नहीं है, तो npm या आपको एक त्रुटि अनुभव करते हैं, पढ़ स्थापना के निर्देश अपने मंच के लिए एक स्टैंडअलोन द्विआधारी मिलता है।

एक बार जब आप CLI स्थापित किया है, चल रहा firebase --version का एक संस्करण रिपोर्ट करना चाहिए 9.0.0 या उच्चतर:

$ firebase --version
9.0.0

लॉग इन करें

भागो firebase login अपने Google खाते CLI कनेक्ट करने के लिए। यह लॉगिन प्रक्रिया को पूरा करने के लिए एक नई ब्राउज़र विंडो खोलेगा। सुनिश्चित करें कि आपने वही खाता चुना है जिसका उपयोग आपने पहले अपना 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 एंड्रॉयड स्टूडियो में। इस फ़ाइल में फायरबेस एसडीके को आपकी मशीन पर चल रहे स्थानीय एमुलेटर से जोड़ने का तर्क है।

फ़ाइल के शीर्ष पर, इस पंक्ति की जाँच करें:

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

हम प्रयोग कर रहे हैं BuildConfig यकीन है कि जब हमारे अनुप्रयोग में चल रहा है हम केवल emulators से कनेक्ट करने के लिए 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) विधि स्थानीय Firestore एमुलेटर को Firebase एसडीके कनेक्ट करने के लिए। एप्लिकेशन में हम का उपयोग करेगा FirebaseUtil.getFirestore() के इस उदाहरण का उपयोग करने के FirebaseFirestore इसलिए हम यह सुनिश्चित है कि हम हमेशा जब में चल रहे इस firestore एमुलेटर से कनेक्ट कर रहे हैं debug मोड।

ऐप चलाएं

आप जोड़ा है, तो google-services.json फ़ाइल ठीक से, परियोजना अब संकलन चाहिए। एंड्रॉयड स्टूडियो क्लिक बिल्ड में> परियोजना के पुनर्निर्माण और सुनिश्चित करें कि वहाँ कोई शेष त्रुटियाँ हैं कि।

में एंड्रॉयड स्टूडियो भागो अपने Android एम्युलेटर पर ऐप्लिकेशन। सबसे पहले आपको "साइन इन" स्क्रीन के साथ प्रस्तुत किया जाएगा। ऐप में साइन इन करने के लिए आप किसी भी ईमेल और पासवर्ड का उपयोग कर सकते हैं। यह साइन इन प्रक्रिया फायरबेस प्रमाणीकरण एमुलेटर से जुड़ रही है, इसलिए कोई वास्तविक प्रमाण-पत्र प्रसारित नहीं किया जा रहा है।

अब नेविगेट करके एम्युलेटर्स यूआई खोलने 4000: http: // स्थानीय होस्ट अपने वेब ब्राउज़र में। तब प्रमाणीकरण टैब पर क्लिक करें और आप अभी बनाए गए खाते देखना चाहिए:

फायरबेस प्रामाणिक एमुलेटर

एक बार जब आप साइन इन प्रक्रिया पूरी कर लेते हैं तो आपको ऐप की होम स्क्रीन देखनी चाहिए:

de06424023ffb4b9.png

जल्द ही हम होम स्क्रीन को पॉप्युलेट करने के लिए कुछ डेटा जोड़ेंगे।

6. फायरस्टोर को डेटा लिखें

इस खंड में हम फायरस्टोर को कुछ डेटा लिखेंगे ताकि हम वर्तमान में खाली होम स्क्रीन को पॉप्युलेट कर सकें।

हमारे अनुप्रयोग में मुख्य मॉडल वस्तु एक रेस्तरां (देखें है model/Restaurant.java )। फायरस्टोर डेटा को दस्तावेज़ों, संग्रहों और उप-संग्रहों में विभाजित किया गया है। हम एक उच्च-स्तरीय संग्रह कहा जाता है में एक दस्तावेज़ के रूप में प्रत्येक रेस्तरां स्टोर करेगा "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" संग्रह। जब दस्तावेज़ जोड़े जाते हैं तो संग्रह निहित रूप से बनाए जाते हैं, इसलिए डेटा लिखने से पहले संग्रह बनाने की कोई आवश्यकता नहीं थी।
  • पीओजेओ का उपयोग करके दस्तावेज़ बनाए जा सकते हैं, जिनका उपयोग हम प्रत्येक रेस्तरां दस्तावेज़ बनाने के लिए करते हैं।
  • add() विधि ताकि हम एक रेस्तरां के लिए एक अद्वितीय ID निर्दिष्ट करने की आवश्यकता नहीं किया था, एक स्वत: जनरेट आईडी के साथ एक संग्रह के लिए कोई दस्तावेज़ कहते हैं।

अब ऐप को फिर से चलाएं और ओवरफ्लो मेनू में "रैंडम आइटम जोड़ें" बटन पर क्लिक करके उस कोड को लागू करें जिसे आपने अभी लिखा है:

95691e9b71ba55e3.png

अब नेविगेट करके एम्युलेटर्स यूआई खोलने 4000: http: // स्थानीय होस्ट अपने वेब ब्राउज़र में। तो फिर इस firestore टैब पर क्लिक करें और आप डेटा आपके द्वारा अभी जोड़ी देखना चाहिए:

फायरबेस प्रामाणिक एमुलेटर

यह डेटा आपकी मशीन के लिए 100% स्थानीय है। वास्तव में, आपके वास्तविक प्रोजेक्ट में अभी तक एक फायरस्टोर डेटाबेस भी नहीं है! इसका मतलब यह है कि बिना किसी परिणाम के इस डेटा को संशोधित करने और हटाने के साथ प्रयोग करना सुरक्षित है।

बधाई हो, आपने अभी-अभी Firestore को डेटा लिखा है! अगले चरण में हम सीखेंगे कि इस डेटा को ऐप में कैसे प्रदर्शित किया जाए।

7. फायरस्टोर से डेटा प्रदर्शित करें

इस चरण में हम सीखेंगे कि फायरस्टोर से डेटा कैसे प्राप्त करें और इसे अपने ऐप में प्रदर्शित करें। इस 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);
        }
    }

अब ऐप फायरस्टोर से डेटा पढ़ने के लिए पूरी तरह से कॉन्फ़िगर किया गया है। ऐप को पुन: चलाने के लिए और आप रेस्तरां पिछले चरण में जोड़ा देखना चाहिए:

9e45f40faefce5d0.png

अब अपने ब्राउज़र में एम्यूलेटर यूआई पर वापस जाएं और रेस्तरां के नामों में से किसी एक को संपादित करें। आपको इसे ऐप में लगभग तुरंत बदलते देखना चाहिए!

8. डेटा को सॉर्ट और फ़िल्टर करें

ऐप वर्तमान में पूरे संग्रह में टॉप-रेटेड रेस्तरां प्रदर्शित करता है, लेकिन एक वास्तविक रेस्तरां ऐप में उपयोगकर्ता डेटा को सॉर्ट और फ़िल्टर करना चाहता है। उदाहरण के लिए ऐप "फिलाडेल्फिया में शीर्ष समुद्री भोजन रेस्तरां" या "कम से कम महंगा पिज्जा" दिखाने में सक्षम होना चाहिए।

ऐप के शीर्ष पर सफेद पट्टी पर क्लिक करने से एक फिल्टर संवाद सामने आता है। इस खंड में हम इस संवाद को काम करने के लिए फायरस्टोर प्रश्नों का उपयोग करेंगे:

६७८९८५७२ए३५६७२ए५.पीएनजी

आइए संपादित 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

यदि आपने इसे अब तक बना लिया है, तो आपने अब फायरस्टोर पर पूरी तरह से काम कर रहे रेस्तरां की सिफारिश देखने वाला ऐप बना लिया है! अब आप वास्तविक समय में रेस्तरां को सॉर्ट और फ़िल्टर कर सकते हैं। अगले कुछ खंडों में हम ऐप में समीक्षा और सुरक्षा पोस्ट कर रहे हैं।

9. उपसंग्रह में डेटा व्यवस्थित करें

इस खंड में हम ऐप में रेटिंग जोड़ेंगे ताकि उपयोगकर्ता अपने पसंदीदा (या कम से कम पसंदीदा) रेस्तरां की समीक्षा कर सकें।

संग्रह और उपसंग्रह

अब तक हमने सभी रेस्तरां डेटा को "रेस्तरां" नामक एक शीर्ष-स्तरीय संग्रह में संग्रहीत किया है। एक उपयोगकर्ता दरों एक रेस्तरां हम एक नया जोड़ना चाहते हैं जब Rating रेस्तरां के लिए वस्तु। इस कार्य के लिए हम एक उपसंग्रह का उपयोग करेंगे। आप एक उपसंग्रह को एक संग्रह के रूप में सोच सकते हैं जो एक दस्तावेज़ से जुड़ा हुआ है। तो प्रत्येक रेस्तरां दस्तावेज़ में रेटिंग दस्तावेज़ों से भरा रेटिंग उपसंग्रह होगा। उपसंग्रह हमारे दस्तावेज़ों को फुलाए बिना या जटिल प्रश्नों की आवश्यकता के बिना डेटा को व्यवस्थित करने में मदद करते हैं।

एक subcollection, कॉल का उपयोग करने के .collection() मूल दस्तावेज़ पर:

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

आप उप-संग्रह तक पहुंच और क्वेरी कर सकते हैं जैसे शीर्ष-स्तरीय संग्रह के साथ, कोई आकार सीमाएं या प्रदर्शन परिवर्तन नहीं होते हैं। आप इस firestore डेटा मॉडल के बारे में अधिक पढ़ सकते हैं यहाँ

लेन-देन में डेटा लिखना

एक जोड़ा जा रहा है Rating उचित subcollection के लिए एक ही बुला आवश्यकता .add() , लेकिन हम भी अद्यतन करने की आवश्यकता Restaurant वस्तु की औसत रेटिंग और रेटिंग की संख्या नए डेटा दिखाता है। यदि हम इन दो परिवर्तनों को करने के लिए अलग-अलग कार्रवाइयों का उपयोग करते हैं तो ऐसी कई दौड़ स्थितियां हैं जिनके परिणामस्वरूप पुराना या गलत डेटा हो सकता है।

यह सुनिश्चित करने के लिए कि रेटिंग ठीक से जोड़ी गई हैं, हम किसी रेस्तरां में रेटिंग जोड़ने के लिए लेनदेन का उपयोग करेंगे। यह लेन-देन कुछ कार्य करेगा:

  • रेस्तरां की वर्तमान रेटिंग पढ़ें और नए की गणना करें
  • उपसंग्रह में रेटिंग जोड़ें
  • रेस्टोरेंट की औसत रेटिंग और रेटिंग की संख्या अपडेट करें

ओपन 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 के बारे में सीखते रहने के लिए, आरंभ करने के लिए यहां कुछ अच्छी जगहें दी गई हैं:

इस कोडलैब में रेस्तरां ऐप "फ्रेंडली ईट्स" उदाहरण एप्लिकेशन पर आधारित था। आपको लगता है कि अनुप्रयोग के लिए स्रोत कोड ब्राउज़ कर सकते हैं यहाँ

वैकल्पिक: उत्पादन के लिए तैनात करें

अभी तक इस ऐप ने केवल Firebase Emulator Suite का ही इस्तेमाल किया है। यदि आप सीखना चाहते हैं कि इस ऐप को वास्तविक फायरबेस प्रोजेक्ट में कैसे परिनियोजित किया जाए, तो अगले चरण पर जारी रखें।

12. (वैकल्पिक) अपना ऐप तैनात करें

अब तक यह ऐप पूरी तरह से स्थानीय रहा है, सभी डेटा फायरबेस एमुलेटर सूट में समाहित है। इस सेक्शन में आप सीखेंगे कि अपने फायरबेस प्रोजेक्ट को कैसे कॉन्फ़िगर करें ताकि यह ऐप प्रोडक्शन में काम करे।

फायरबेस प्रमाणीकरण

Firebase में करने के लिए प्रमाणीकरण अनुभाग और नेविगेट करने के लिए जाना consle साइन-इन प्रदाताओं टैब

ईमेल साइन-इन विधि सक्षम करें:

334ef7f6ff4da4ce.png

इस firestore

डेटाबेस बनाएं

सांत्वना के इस firestore अनुभाग के लिए और नेविगेट क्लिक डाटाबेस बनाएँ:

  1. संकेत दिए जाने के बारे में सुरक्षा नियम बंद मोड में शुरू करने के लिए चुनते हैं, तो हम उन नियमों जल्द ही अपडेट करेंगे।
  2. डेटाबेस स्थान चुनें जिसे आप अपने ऐप के लिए उपयोग करना चाहते हैं। ध्यान दें कि चयन एक डेटाबेस स्थान के लिए एक स्थायी निर्णय है और इसे बदलने के लिए आप एक नया प्रोजेक्ट बनाने के लिए होगा। एक परियोजना स्थान चयन पर अधिक जानकारी के लिए, देखें प्रलेखन

नियम तैनात करें

आपके द्वारा पहले लिखे गए सुरक्षा नियमों को लागू करने के लिए, कोडलैब निर्देशिका में निम्न आदेश चलाएँ:

$ 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

ध्यान दें कि अनुक्रमणिका निर्माण तात्कालिक नहीं है, आप फ़ायरबेस कंसोल में प्रगति की निगरानी कर सकते हैं।

ऐप को कॉन्फ़िगर करें

में FirebaseUtil वर्ग हम जब डिबग मोड में emulators से कनेक्ट करने में Firebase एसडीके कॉन्फ़िगर किया गया:

public class FirebaseUtil {

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

    // ...
}

यदि आप अपने वास्तविक फायरबेस प्रोजेक्ट के साथ अपने ऐप का परीक्षण करना चाहते हैं तो आप या तो कर सकते हैं:

  1. ऐप को रिलीज़ मोड में बनाएं और इसे डिवाइस पर चलाएं।
  2. अस्थायी रूप से बदल sUseEmulators को false और फिर अनुप्रयोग चलाने के।

नोट आप ऐप्लिकेशन से प्रस्थान कर और ठीक से उत्पादन करने के लिए कनेक्ट करने के लिए पुन: प्रवेश करना पड़ सकता है।