Google is committed to advancing racial equity for Black communities. See how.
This page was translated by the Cloud Translation API.
Switch to English

ক্লাউড ফায়ারস্টোর অ্যান্ড্রয়েড কোডল্যাব

লক্ষ্য

এই কোডল্যাবে আপনি ক্লাউড ফায়ারস্টোর দ্বারা সমর্থিত অ্যান্ড্রয়েডে একটি রেস্তোঁরা সুপারিশ অ্যাপ্লিকেশন তৈরি করবেন। আপনি কীভাবে শিখবেন:

  • অ্যান্ড্রয়েড অ্যাপ থেকে ফায়ারস্টোরে ডেটা পড়ুন এবং লিখুন
  • রিয়েলটাইমে ফায়ার স্টোর ডেটার পরিবর্তনগুলি শুনুন
  • ফায়ার স্টোর ডেটা সুরক্ষিত করতে ফায়ারবেস প্রমাণীকরণ এবং সুরক্ষা বিধিগুলি ব্যবহার করুন
  • জটিল ফায়ারস্টোর প্রশ্ন লিখুন

পূর্বশর্ত

এই কোডল্যাবটি শুরু করার আগে আপনার কাছে নিশ্চিত হয়ে নিন:

  • অ্যান্ড্রয়েড স্টুডিও ৪.০ বা তার বেশি
  • একটি অ্যান্ড্রয়েড এমুলেটর
  • নোড.জেএস সংস্করণ 10 বা উচ্চতর
  • জাভা 8 বা তারও বেশি সংস্করণ
  1. আপনার গুগল অ্যাকাউন্ট দিয়ে ফায়ারবেস কনসোলে সাইন ইন করুন।
  2. ফায়ারবেস কনসোলে , প্রকল্প যুক্ত করুন ক্লিক করুন
  3. নীচের স্ক্রিন ক্যাপচারে প্রদর্শিত হিসাবে, আপনার ফায়ারবেস প্রকল্পের জন্য একটি নাম লিখুন (উদাহরণস্বরূপ, "বন্ধুত্বপূর্ণ খাওয়া") এবং চালিয়ে যান ক্লিক করুন।

9d2f625aebcab6af.png

  1. আপনাকে গুগল অ্যানালিটিক্স সক্ষম করতে বলা হতে পারে, এই কোডল্যাবের উদ্দেশ্যে আপনার নির্বাচনের কোনও বিষয় আসে না।
  2. এক মিনিট বা তার পরে আপনার ফায়ারবেস প্রকল্পটি প্রস্তুত থাকবে। চালিয়ে ক্লিক করুন।

কোডটি ডাউনলোড করুন

এই কোডল্যাবের জন্য নমুনা কোডটি ক্লোন করতে নিম্নলিখিত কমান্ডটি চালান। এটি আপনার মেশিনে friendlyeats-android নামে একটি ফোল্ডার তৈরি করবে:

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

আপনার মেশিনে গিট না থাকলে আপনি গিটহাব থেকে সরাসরি কোডটি ডাউনলোড করতে পারেন।

প্রকল্পটি অ্যান্ড্রয়েড স্টুডিওতে আমদানি করুন। আপনি সম্ভবত কিছু সংকলন ত্রুটি দেখতে পেয়েছেন বা গুপ্ত google-services.json ফাইল সম্পর্কে একটি সতর্কতা দেখতে পাবেন। আমরা এটি পরবর্তী বিভাগে সংশোধন করব।

ফায়ারবেস কনফিগারেশন যুক্ত করুন

  1. ফায়ারবেস কনসোলে , বাম এনএভিতে প্রকল্প ওভারভিউ নির্বাচন করুন। প্ল্যাটফর্মটি নির্বাচন করতে অ্যান্ড্রয়েড বোতামটি ক্লিক করুন। যখন কোনও প্যাকেজ নামের জন্য অনুরোধ করা হয় com.google.firebase.example.fireeats ব্যবহার com.google.firebase.example.fireeats

73d151ed16016421.png

  1. অ্যাপ্লিকেশনটিকে নিবন্ধিত করুন এ ক্লিক করুন এবং google-services.json ফাইলটি ডাউনলোড করতে নির্দেশাবলী অনুসরণ করুন এবং এটি নমুনা কোডের app/ ফোল্ডারে সরান। তারপরে Next ক্লিক করুন।

এই কোডল্যাবে আপনি স্থানীয়ভাবে ক্লাউড ফায়ারস্টোর এবং ফায়ারবেস পরিষেবাগুলি অনুকরণ করতে ফায়ারবেস এমুলেটর স্যুটটি ব্যবহার করবেন। এটি আপনার অ্যাপ্লিকেশনটি তৈরি করতে নিরাপদ, দ্রুত এবং বিনামূল্যে স্থানীয় বিকাশের পরিবেশ সরবরাহ করে।

ফায়ারবেস সিএলআই ইনস্টল করুন

প্রথমে আপনাকে ফায়ারবেস সিএলআই ইনস্টল করতে হবে। এটি করার সহজতম উপায় হল npm ব্যবহার করা:

npm install -g firebase-tools

আপনার যদি npm না থাকে বা আপনি কোনও ত্রুটি অনুভব করেন, আপনার প্ল্যাটফর্মের জন্য স্ট্যান্ড্যালোন বাইনারি পেতে ইনস্টলেশন সংক্রান্ত নির্দেশাবলীটি পড়ুন।

একবার আপনি সিএলআই ইনস্টল করার পরে, firebase --version চলমান 9.0.0 বা 9.0.0 সংস্করণের রিপোর্ট করা উচিত:

$ firebase --version
9.0.0

প্রবেশ করুন

আপনার গুগল অ্যাকাউন্টে সিএলআই সংযুক্ত করতে firebase login চালান। এটি লগইন প্রক্রিয়াটি সম্পূর্ণ করতে একটি নতুন ব্রাউজার উইন্ডো খুলবে। এর আগে আপনার ফায়ারবেস প্রকল্পটি তৈরি করার সময় আপনি যে অ্যাকাউন্টটি ব্যবহার করেছেন তা বেছে নেওয়ার বিষয়টি নিশ্চিত করুন।

friendlyeats-android ফোল্ডারের মধ্যে থেকে firebase use --add আপনার ফায়ারবেস প্রকল্পের সাথে আপনার স্থানীয় প্রকল্পটি সংযুক্ত করতে অ্যাড। আপনি যে প্রকল্পটি তৈরি করেছেন তা নির্বাচন করার জন্য অনুরোধগুলি অনুসরণ করুন এবং যদি একটি উপাধি প্রবেশের default চয়ন করতে বলা হয়।

এখন প্রথমবারের মতো ফায়ারবেস এমুলেটর স্যুট এবং ফ্রেন্ডলি ইটস অ্যান্ড্রয়েড অ্যাপটি চালানোর সময়।

অনুকরণকারী চালান

আপনার টার্মিনালে friendlyeats-android ডিরেক্টরি থেকে firebase emulators:start চালান: firebase emulators:start করা শুরু করুন। আপনার এই জাতীয় লগগুলি দেখতে হবে:

$ 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;

আমরা যখন অ্যাপ্লিকেশনটি debug মোডে চলছে তখনই কেবলমাত্র BuildConfig সাথে সংযোগ স্থাপন করব তা নিশ্চিত করতে আমরা BuildConfig ব্যবহার BuildConfig । যখন আমরা অ্যাপ্লিকেশনটি 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) এসডিকে স্থানীয় ফায়ার স্টোর এমুলেটরের সাথে সংযুক্ত করতে useEmulator(host, port) পদ্ধতিটি ব্যবহার করছে। অ্যাপ্লিকেশন সর্বত্র আমরা ব্যবহার করবে FirebaseUtil.getFirestore() এই ক্ষেত্রটিকেই অ্যাক্সেস করতে FirebaseFirestore তাই আমরা নিশ্চিত যে আমরা সবসময় যখন চলমান Firestore এমুলেটর সঙ্গে সংযোগ স্থাপন করছে হয় debug মোড।

অ্যাপটি চালান Run

আপনি যদি google-services.json ফাইলটি যথাযথভাবে যোগ করেছেন তবে এখন প্রকল্পটি সংকলন করা উচিত। অ্যান্ড্রয়েড স্টুডিওতে বিল্ড > পুনর্নির্মাণ প্রকল্পটি ক্লিক করুন এবং নিশ্চিত করুন যে কোনও ত্রুটি অবশিষ্ট নেই।

অ্যান্ড্রয়েড স্টুডিওতে আপনার অ্যান্ড্রয়েড এমুলেটরটিতে অ্যাপ্লিকেশন চালান । প্রথমে আপনাকে একটি "সাইন ইন" স্ক্রিন উপস্থাপন করা হবে। অ্যাপটিতে সাইন ইন করতে আপনি যে কোনও ইমেল এবং পাসওয়ার্ড ব্যবহার করতে পারেন। এই সাইন ইন প্রক্রিয়াটি ফায়ারবেস প্রমাণীকরণ এমুলেটরের সাথে সংযোগ স্থাপন করছে, সুতরাং কোনও আসল শংসাপত্র প্রেরণ করা হচ্ছে না।

এখন আপনার ওয়েব ব্রাউজারে http: // লোকালহোস্ট: 4000 তে নেভিগেট করে এমুলেটর ইউআই খুলুন। তারপরে প্রমাণীকরণ ট্যাবে ক্লিক করুন এবং আপনার সবেমাত্র তৈরি করা অ্যাকাউন্টটি দেখতে হবে:

ফায়ারবেস আথ এমুলেটর

একবার আপনি সাইন ইন প্রক্রিয়াটি শেষ করার পরে আপনার অ্যাপ্লিকেশনটির হোম স্ক্রিনটি দেখতে হবে:

de06424023ffb4b9.png

শীঘ্রই আমরা হোম স্ক্রিনটি জনপ্রিয় করতে কিছু ডেটা যুক্ত করব।

এই বিভাগে আমরা ফায়ার স্টোরে কিছু ডেটা লিখব যাতে আমরা বর্তমানে খালি হোম স্ক্রিনটি তৈরি করতে পারি।

আমাদের অ্যাপ্লিকেশনটির প্রধান মডেল অবজেক্টটি একটি রেস্তোঁরা ( 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" সংগ্রহের একটি রেফারেন্স পেয়ে শুরু করেছি। নথি যুক্ত করা হলে সংগ্রহগুলি স্পষ্টতই তৈরি করা হয়, সুতরাং ডেটা লেখার আগে সংগ্রহটি তৈরি করার দরকার ছিল না।
  • POJO ব্যবহার করে নথি তৈরি করা যেতে পারে, যা আমরা প্রতিটি রেস্তোরাঁর ডক তৈরি করতে ব্যবহার করি।
  • add() পদ্ধতিটি একটি সংগ্রহের সাথে একটি স্বতঃ উত্পাদিত আইডি সহ একটি দস্তাবেজ যুক্ত করে, তাই আমাদের প্রতিটি রেস্তোঁরাটির জন্য একটি অনন্য আইডি নির্দিষ্ট করার প্রয়োজন হয়নি।

এখনই অ্যাপটি চালনা করুন এবং আপনার সবেমাত্র লেখা কোডটি চাওয়ার জন্য ওভারফ্লো মেনুতে "র্যান্ডম আইটেমগুলি যুক্ত করুন" বোতামটি ক্লিক করুন:

95691e9b71ba55e3.png

এখন আপনার ওয়েব ব্রাউজারে http: // লোকালহোস্ট: 4000 তে নেভিগেট করে এমুলেটর ইউআই খুলুন। তারপরে ফায়ারস্টোর ট্যাবে ক্লিক করুন এবং আপনার সবেমাত্র যুক্ত করা ডেটাটি দেখতে হবে:

ফায়ারবেস আথ এমুলেটর

এই ডেটাটি আপনার মেশিনে 100% স্থানীয়। আসলে, আপনার আসল প্রকল্পটিতে এখনও একটি ফায়ার স্টোর ডাটাবেস নেই! এর অর্থ এটি ছাড়াই এই ডেটাটি সংশোধন ও মোছা নিয়ে পরীক্ষা করা নিরাপদ।

অভিনন্দন, আপনি কেবল ফায়ার স্টোরে ডেটা লিখেছেন! পরবর্তী পদক্ষেপে আমরা অ্যাপটিতে এই ডেটাটি প্রদর্শন করতে শিখব।

এই পদক্ষেপে আমরা ফায়ার স্টোর থেকে ডেটা পুনরুদ্ধার করতে এবং এটি আমাদের অ্যাপে প্রদর্শন করব তা শিখব। ফায়ারস্টোর থেকে ডেটা পড়ার প্রথম পদক্ষেপটি Query তৈরি করা। onCreate() পদ্ধতিটি পরিবর্তন করুন:

        mFirestore = FirebaseUtil.getFirestore();

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

এখন আমরা ক্যোয়ারীটি শুনতে চাই, যাতে আমরা সমস্ত মিলে যাওয়া নথি পাই এবং আসল সময়ে ভবিষ্যতের আপডেটগুলি সম্পর্কে অবহিত হই। যেহেতু আমাদের চূড়ান্ত লক্ষ্যটি এই RecyclerView একটি RecyclerView সাথে আবদ্ধ করা, তাই আমাদের ডেটা শোনার জন্য একটি RecyclerView.Adapter শ্রেণি তৈরি করতে হবে।

FirestoreAdapter ক্লাসটি খুলুন, যা ইতিমধ্যে ইতিমধ্যে প্রয়োগ করা হয়েছে। প্রথমে, অ্যাডাপ্টারটি EventListener বাস্তবায়ন EventListener এবং onEvent ফাংশনটি সংজ্ঞায়িত করি যাতে এটি ফায়ারস্টোর ক্যোয়ারিতে আপডেটগুলি পেতে পারে:

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);
        }
    }

ফায়ারস্টোর থেকে ডেটা পড়তে এখন অ্যাপটি সম্পূর্ণরূপে কনফিগার করা হয়েছে ured অ্যাপ্লিকেশনটি আবার চালনা করুন এবং আপনি আগের পদক্ষেপে যে রেস্তোঁরাগুলি যুক্ত করেছেন তা দেখতে পাওয়া উচিত:

9e45f40faefce5d0.png

এখন আপনার ব্রাউজারে এমুলেটর ইউআইতে ফিরে যান এবং রেস্তোঁরাগুলির একটির সম্পাদনা করুন। আপনার এটি প্রায় তাত্ক্ষণিকভাবে অ্যাপে পরিবর্তন হওয়া উচিত!

অ্যাপ্লিকেশনটি পুরো সংগ্রহ জুড়ে শীর্ষ-রেটযুক্ত রেস্তোঁরাগুলি প্রদর্শন করে তবে একটি বাস্তব রেস্তোঁরা অ্যাপ্লিকেশনটিতে ব্যবহারকারী ডেটা বাছাই এবং ফিল্টার করতে চান। উদাহরণস্বরূপ অ্যাপ্লিকেশনটিকে "ফিলাডেলফিয়ার শীর্ষ সীফুড রেস্তোরাঁ" বা "সবচেয়ে ব্যয়বহুল পিজ্জা" দেখাতে সক্ষম হওয়া উচিত।

অ্যাপের শীর্ষে সাদা বারটি ক্লিক করা একটি ফিল্টার সংলাপ নিয়ে আসে। এই বিভাগে আমরা ফায়ারস্টোর অনুসন্ধানগুলি এই ডায়ালগটিকে কাজ করতে ব্যবহার করব:

67898572a35672a5.png

আসুন সম্পাদনার onFilter() পদ্ধতি MainActivity.java । এই পদ্ধতিটি একটি Filters অবজেক্ট গ্রহণ করে যা ফিল্টার সংলাপের আউটপুট ক্যাপচারের জন্য তৈরি করা সহায়ক সহায়ক er ফিল্টারগুলি থেকে কোয়েরি তৈরি করতে আমরা এই পদ্ধতিটি পরিবর্তন করব:

    @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 ক্লজগুলি orderBy করে এবং orderBy করে।

অ্যাপ্লিকেশনটি আবার চালান এবং সর্বাধিক জনপ্রিয় কম দামের রেস্তোরাঁগুলি দেখানোর জন্য নিম্নলিখিত ফিল্টারটি নির্বাচন করুন:

7a67a8a400c80c50.png

আপনি এখন কেবলমাত্র কম দামের বিকল্পগুলি সহ রেস্তোঁরাগুলির ফিল্টারড তালিকাটি দেখতে পান:

a670188398c3c59.png

যদি আপনি এখন পর্যন্ত এটি তৈরি করে থাকেন তবে আপনি এখন ফায়ার স্টোরে সম্পূর্ণরূপে কার্যকরী রেস্তোঁরা সুপারিশ দেখার অ্যাপ তৈরি করেছেন! আপনি এখন রিয়েল টাইমে রেস্তোঁরাগুলিকে বাছাই করতে এবং ফিল্টার করতে পারেন। পরবর্তী কয়েকটি বিভাগে আমরা অ্যাপটিতে পর্যালোচনা এবং সুরক্ষা পোস্ট করি।

এই বিভাগে আমরা অ্যাপটিতে রেটিং যুক্ত করব যাতে ব্যবহারকারীরা তাদের প্রিয় (বা কমপক্ষে প্রিয়) রেস্তোঁরাগুলি পর্যালোচনা করতে পারেন।

সংগ্রহ এবং উপ-সংগ্রহসমূহ

এখনও অবধি আমরা সমস্ত রেস্তোঁরাার ডেটা "রেস্তোঁরাগুলি" নামে একটি উচ্চ-স্তরের সংগ্রহে সংরক্ষণ করেছি। যখন কোনও ব্যবহারকারী কোনও রেস্তোঁরা রেট করে আমরা রেস্তোঁরাগুলিতে একটি নতুন Rating অবজেক্ট যুক্ত করতে চাই। এই কাজের জন্য আমরা একটি উপ-সংগ্রহ ব্যবহার করব। আপনি কোনও উপস্তরের একটি সংগ্রহ হিসাবে মনে করতে পারেন যা কোনও দস্তাবেজের সাথে সংযুক্ত। সুতরাং প্রতিটি রেস্তোরাঁর নথিতে রেটিংয়ের ডকুমেন্টগুলি পূর্ণ একটি রেটিং উপ-সংগ্রহ থাকবে। উপ-সংগ্রহগুলি আমাদের দস্তাবেজগুলি ফোটানো বা জটিল প্রশ্নের প্রয়োজন ছাড়াই ডেটা সংগঠিত করতে সহায়তা করে।

.collection() অ্যাক্সেস করতে, .collection() নথিতে কল .collection() কল করুন:

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

আপনি একটি শীর্ষ-স্তরের সংগ্রহের মতো উপ-সংগ্রহটি অ্যাক্সেস এবং ক্যোয়ার করতে পারেন, আকারের কোনও সীমাবদ্ধতা বা পারফরম্যান্স পরিবর্তন নেই। আপনি এখানে ফায়ারস্টোর ডেটা মডেল সম্পর্কে আরও পড়তে পারেন।

কোনও লেনদেনে ডেটা লেখা

যথাযথ .add() একটি Rating করার জন্য কেবল .add() কল করা দরকার তবে নতুন ডেটা প্রতিফলিত করার জন্য আমাদের Restaurant .add() গড় রেটিং এবং রেটিংয়ের সংখ্যাও আপডেট করতে হবে। আমরা যদি এই দুটি পরিবর্তন করতে আলাদা অপারেশন ব্যবহার করি তবে এখানে প্রচুর রেস শর্ত রয়েছে যা বাসি বা ভুল ডেটা হতে পারে।

রেটিংগুলি যথাযথভাবে যুক্ত করা হয়েছে তা নিশ্চিত করার জন্য, আমরা কোনও রেস্তোঁরায় রেটিং যুক্ত করার জন্য একটি লেনদেন ব্যবহার করব। এই লেনদেনটি কয়েকটি ক্রিয়া সম্পাদন করবে:

  • রেস্তোঁরাটির বর্তমান রেটিং পড়ুন এবং নতুনটি গণনা করুন
  • উপমঞ্চে রেটিং যুক্ত করুন
  • রেস্তোঁরাটির গড় রেটিং এবং রেটিংয়ের সংখ্যা আপডেট করুন

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() ফাংশনে শ্রোতাদের লেনদেনের ফলাফলের প্রতিক্রিয়া জানানোর জন্য onRating() যুক্ত করা হয়।

এখন অ্যাপ্লিকেশনটি আবার চালান এবং রেস্তোঁরাগুলির একটিতে ক্লিক করুন, যা রেস্তোঁরা বিশদ স্ক্রিনটি নিয়ে আসে। একটি পর্যালোচনা যুক্ত করা শুরু করতে + বোতামটি ক্লিক করুন। বেশ কয়েকটি তারা বাছাই করে এবং কিছু পাঠ্য প্রবেশ করে একটি পর্যালোচনা যুক্ত করুন।

78fa16cdf8ef435a.png

সাবমিট হিট করলে লেনদেন বন্ধ হয়ে যাবে। লেনদেন শেষ হলে, আপনি নীচে প্রদর্শিত আপনার পর্যালোচনা এবং রেস্তোঁরাটির পর্যালোচনা গণনার একটি আপডেট দেখতে পাবেন:

f9e670f40bd615b0.png

অভিনন্দন! আপনার কাছে এখন ক্লাউড ফায়ার স্টোরে নির্মিত একটি সামাজিক, স্থানীয়, মোবাইল রেস্তোঁরা পর্যালোচনা অ্যাপ্লিকেশন রয়েছে। আমি শুনি সেগুলি আজকাল খুব জনপ্রিয়।

এখনও পর্যন্ত আমরা এই অ্যাপ্লিকেশনটির সুরক্ষা বিবেচনা করি নি। আমরা কীভাবে জানি যে ব্যবহারকারীগণ কেবলমাত্র সঠিক নিজস্ব ডেটা পড়তে এবং লিখতে পারেন? ফায়ার স্টোর ডাটাবেসগুলি সুরক্ষা বিধি নামে একটি কনফিগারেশন ফাইল দ্বারা সুরক্ষিত।

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;
    }
  }
}

আসুন অযাচিত ডেটা অ্যাক্সেস বা পরিবর্তনগুলি রোধ করতে এই নিয়মগুলি পরিবর্তন করুন, 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;
      }
    }
  }
}

এই নিয়মগুলি ক্লায়েন্টদের কেবল নিরাপদ পরিবর্তন করতে পারে তা নিশ্চিত করার জন্য অ্যাক্সেসকে সীমাবদ্ধ করে। উদাহরণস্বরূপ কোনও রেস্তোরাঁর দস্তাবেজের আপডেটগুলি কেবলমাত্র নামগুলি বা অন্য কোনও অপরিবর্তনীয় ডেটা নয়, রেটিংগুলিকে পরিবর্তন করতে পারে। ব্যবহারকারী আইডি সাইন ইন থাকা ব্যবহারকারীটির সাথে মেলে তবেই রেটিংগুলি তৈরি করা যেতে পারে, যা স্পোফিং প্রতিরোধ করে।

সুরক্ষা বিধি সম্পর্কে আরও পড়তে, ডকুমেন্টেশনটি দেখুন

আপনি এখন ফায়ার স্টোর শীর্ষে একটি সম্পূর্ণ বৈশিষ্ট্যযুক্ত অ্যাপ তৈরি করেছেন। আপনি সর্বাধিক গুরুত্বপূর্ণ ফায়ার স্টোর বৈশিষ্ট্যগুলি সম্পর্কে শিখেছেন:

  • দলিল এবং সংগ্রহ
  • ডেটা পড়া এবং লেখা
  • বাছাই এবং প্রশ্নের সাথে ফিল্টারিং
  • উপ-সংগ্রহ
  • লেনদেন

আরও জানুন

ফায়ার স্টোর সম্পর্কে শিখতে রাখতে, এখানে শুরু করার জন্য কয়েকটি ভাল জায়গা রয়েছে:

এই কোডল্যাবে রেস্তোঁরা অ্যাপটি "বন্ধুত্বপূর্ণ খাওয়া" উদাহরণ প্রয়োগের ভিত্তিতে ছিল। আপনি এখানে এই অ্যাপ্লিকেশনটির জন্য উত্স কোডটি ব্রাউজ করতে পারেন।

Alচ্ছিক: উত্পাদনে মোতায়েন করুন

এখনও অবধি এই অ্যাপ্লিকেশনটি কেবল ফায়ারবেস এমুলেটর স্যুট ব্যবহার করেছে। আপনি যদি এই অ্যাপ্লিকেশনটিকে সত্যিকারের ফায়ারবেস প্রকল্পে স্থাপন করতে চান তা জানতে চাইলে পরবর্তী পদক্ষেপে চালিয়ে যান।

এখন পর্যন্ত এই অ্যাপ্লিকেশনটি সম্পূর্ণ স্থানীয় ছিল, সমস্ত ডেটা ফায়ারবেস এমুলেটর স্যুটে থাকে। এই বিভাগে আপনি কীভাবে আপনার ফায়ারবেস প্রকল্পটি কনফিগার করবেন তা শিখবেন যাতে এই অ্যাপ্লিকেশনটি উত্পাদনে কাজ করে।

ফায়ারবেস প্রমাণীকরণ

ফায়ারবেস কনসেলে প্রমাণীকরণ বিভাগে যান এবং সাইন-ইন সরবরাহকারী ট্যাবে নেভিগেট করুন

ইমেল সাইন-ইন পদ্ধতি সক্ষম করুন:

334ef7f6ff4da4ce.png

ফায়ার স্টোর

ডাটাবেস তৈরি করুন

কনসোলের ফায়ারস্টোর বিভাগে নেভিগেট করুন এবং ডেটাবেস তৈরি করুন ক্লিক করুন :

  1. সুরক্ষা বিধিগুলি সম্পর্কে জিজ্ঞাসা করা হলে লকড মোডে শুরু করা বেছে নেওয়া হয়, আমরা শীঘ্রই এই বিধিগুলি আপডেট করব।
  2. আপনি আপনার অ্যাপ্লিকেশনটির জন্য যে ডাটাবেস অবস্থানটি ব্যবহার করতে চান তা চয়ন করুন। নোট করুন যে একটি ডাটাবেসের অবস্থান নির্বাচন একটি স্থায়ী সিদ্ধান্ত এবং এটি পরিবর্তন করতে আপনাকে একটি নতুন প্রকল্প তৈরি করতে হবে। কোনও প্রকল্পের অবস্থান চয়ন করার বিষয়ে আরও তথ্যের জন্য ডকুমেন্টেশন দেখুন

বিধি মোতায়েন করুন

আপনি পূর্বে লিখেছেন সুরক্ষা বিধি মোতায়েন করতে, কোডলব ডিরেক্টরিতে নিম্নলিখিত কমান্ডটি চালান:

$ firebase deploy --only firestore:rules

এটি আপনার প্রকল্পে firestore.rules এর বিষয়বস্তু মোতায়েন করবে, যা আপনি কনসোলে রুলস ট্যাবে নেভিগেট করে নিশ্চিত করতে পারবেন।

সূচি মোতায়েন করুন

ফ্রেন্ডলি ইটস অ্যাপ্লিকেশনটিতে জটিল বাছাই এবং ফিল্টারিং রয়েছে যার জন্য অনেকগুলি কাস্টম যৌগিক সূচক প্রয়োজন। এগুলি ফায়ারবেস কনসোলে হাতে তৈরি করা যেতে পারে তবে firestore.indexes.json ফাইলে তাদের সংজ্ঞা লিখতে এবং ফায়ারবেস সিএলআই ব্যবহার করে তাদের স্থাপন করা সহজ।

আপনি যদি 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 ক্লাসে আমরা ফায়ারবেস এসডিকে কনফিগার করেছিলাম যখন ডিবাগ মোডে থাকে তখন এমুলেটরগুলির সাথে সংযোগ স্থাপন করতে:

public class FirebaseUtil {

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

    // ...
}

আপনি যদি আপনার আসল ফায়ারবেস প্রকল্পের সাহায্যে আপনার অ্যাপ্লিকেশনটি পরীক্ষা করতে চান তবে আপনি এটি করতে পারেন:

  1. অ্যাপটি রিলিজ মোডে তৈরি করুন এবং এটিকে একটি ডিভাইসে চালান।
  2. অস্থায়ীভাবে sUseEmulators false পরিবর্তন করুন এবং আবার অ্যাপ্লিকেশন চালান run

নোট করুন যে সঠিকভাবে উত্পাদনে সংযোগ করতে আপনাকে অ্যাপ থেকে সাইন আউট করতে এবং আবার সাইন ইন করতে হতে পারে।