unipin
unipin

Reputation: 309

How to refresh data in FirebaseAdapter using FirebaseUI when query is changed?

I want to allow users to sort and filter data. I have this implementation of Firebase Adapter and everything is working great. When I want to filter data using e.g. price, data in RecyclerView is not changing. Can you please help and tell what am doing wrong?

This is the query - depends on what user selected from Spinner:

Query query;

if (!priceLower.equals("Any")) {    // option from Spinner
    query = FirebaseDatabase.getInstance()
            .getReference()
            .child("Students")
            .orderByChild("price")
            .startAt(priceLower)
            .limitToLast(50);
} else if (!priceHigher.equals("Any")) {
    query = FirebaseDatabase.getInstance()
            .getReference()
            .child("Students")
            .orderByChild("price")
            .endAt(priceHigher)
            .limitToLast(50);
} else {
    query = FirebaseDatabase.getInstance()
            .getReference()
            .child("Students")
            .orderByChild("price")
            .limitToLast(50);
}

getData(query);

This is the method to fetch data from Firebase:

 public void getData(Query query) {
        FirebaseRecyclerOptions<Students> firebaseOptions =
                new FirebaseRecyclerOptions.Builder<Students>()
                        .setQuery(query, Students.class)
                        .build();

        FirebaseAdapter = new FirebaseRecyclerAdapter<Students, StudentsHolder>(firebaseOptions) {
            @NonNull
            @Override
            public StudentsHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_students, parent, false);
                return new StudentsHolder(view);
            }
            @Override
            protected void onBindViewHolder(@NonNull StudentsHolder holder, int position, @NonNull final Students student) {
                holder.setName(student.getName());
                holder.setPrice(student.getPrice());

                holder.itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                       // ...
                    }
                });
            }
            @Override
            public void onDataChanged() {       
                progressDialog.setVisibility(View.GONE);
                mRecyclerView.setAdapter(FirebaseAdapter);    
            }
        };
    }

Upvotes: 4

Views: 466

Answers (2)

Alex Mamo
Alex Mamo

Reputation: 1

To solve this, you should add at the end of your getData() method, the following line of code:

FirebaseAdapter.startListening();

This means that everytime you change the query, you create and set a new adapter and you also start listening for changes.

Upvotes: 2

Nishita
Nishita

Reputation: 924

@Override
        public void onDataChanged() {       
            progressDialog.setVisibility(View.GONE);
            mRecyclerView.setAdapter(FirebaseAdapter);    
        }

This method is called only when data on firebase database is changed. But according to your requirement, this data remains the same and only your applied filter or sorting method is changing. Therefore this method will never be called and firebaseadapter will reflect original query only.

Try it this way:

   public void getData(Query query) {
    FirebaseRecyclerOptions<Students> firebaseOptions =
            new FirebaseRecyclerOptions.Builder<Students>()
                    .setQuery(query, Students.class)
                    .build();

    FirebaseAdapter = new FirebaseRecyclerAdapter<Students, StudentsHolder>(firebaseOptions) {
        @NonNull
        @Override
        public StudentsHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_students, parent, false);
            return new StudentsHolder(view);
        }
        @Override
        protected void onBindViewHolder(@NonNull StudentsHolder holder, int position, @NonNull final Students student) {
            holder.setName(student.getName());
            holder.setPrice(student.getPrice());

            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                   // ...
                }
            });
        }
        @Override
        public void onDataChanged() {       

        }
    };

     progressDialog.setVisibility(View.GONE);
     mRecyclerView.setAdapter(FirebaseAdapter);   
}

getData() method should be called whenever your filter is changed.

Upvotes: 0

Related Questions