Search code examples
androidfirebasefirebase-realtime-databaseandroid-recyclerviewfirebaseui

Selective retrieval of data from Firebase to FirebaseRecyclerAdapter


In my Android application, I am using RecyclerView with CardView. The contents of the RecyclerView are fetched from Firebase Realtime Database. For that I have used FirebaseRecyclerAdapter from FirebaseUI. The entries in the database correspond to POJO of class Bus.

public class Bus {
    private String source;
    private String destination;
    private long available;
    private String date;
    private long fare;

    Bus() {

    }

    Bus(String source,String destination,long available,String date,long fare) {
        this.source = source;
        this.destination = destination;
        this.available = available;
        this.date = date;
        this.fare = fare;
    }

    public long getAvailable() {
        return available;
    }

    public long getFare() {
        return fare;
    }

    public String getDate() {
        return date;
    }

    public String getDestination() {
        return destination;
    }

    public String getSource() {
        return source;
    }

    public void setAvailable(long available) {
        this.available = available;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public void setDestination(String destination) {
        this.destination = destination;
    }

    public void setFare(long fare) {
        this.fare = fare;
    }

    public void setSource(String source) {
        this.source = source;
    }

}

In an activity, I accept the source, destination and date from the user. My intention is to display only the relevant data in the RecyclerView. This is my FirebaseRecyclerAdapter code:

FirebaseRecyclerAdapter<Bus,BusViewHolder> firebaseRecyclerAdapter = new     FirebaseRecyclerAdapter<Bus,BusViewHolder>(Bus.class,R.layout.bus_card,BusViewHolder.class,mDatabase) {
        @Override
        protected void populateViewHolder(BusViewHolder viewHolder,Bus model,int position) {
            if(model.getSource().equals(source) && model.getDestination().equals(destination) && model.getDate().equals(date)) // This is the criteria for displaying the card
            {
                viewHolder.setSource(model.getSource());
                viewHolder.setDestination(model.getDestination());
                viewHolder.setAvailable(model.getAvailable());
                viewHolder.setDate(model.getDate());
                viewHolder.setFare(model.getFare());
            }
        }

    };
    recyclerView.setAdapter(firebaseRecyclerAdapter);

Here is my ViewHolder:

public static class BusViewHolder extends RecyclerView.ViewHolder {
    View mView;

    public BusViewHolder(View itemView) {
        super(itemView);
        mView = itemView;
    }

    public void setSource(String source) {
        TextView src = mView.findViewById(R.id.source);
        src.setText("Source " + source);
    }

    public void setDestination(String destination) {
        TextView dest = mView.findViewById(R.id.destination);
        dest.setText("Destination " + destination);
    }

    public void setDate(String date) {
        TextView dte = mView.findViewById(R.id.date);
        dte.setText("Date " + date);
    }

    public void setAvailable(long available) {
        TextView avail = mView.findViewById(R.id.available);
        avail.setText("Available Seats " + Long.toString(available));
    }

    public void setFare(long fare) {
        TextView fre = mView.findViewById(R.id.fare);
        fre.setText("Fare " + Long.toString(fare));
    }
}

The problem with this approach is that it displays the relevant cards, however there are empty cards for data which does not satisfy the condition. Is it possible to selectively retrieve data into the FirebaseRecyclerAdapter? Currently, the total number of cards created in the RecyclerView is equal to the total entries in the database.


Solution

  • I used query object to retrieve selectively from the Realtime Database. As query doesn't support multiple orderby clauses, I had to add an additional field in my node. This is the updated firebaserecycleradapter

    query = mDatabase.orderByChild("sourcedestinationdate").equalTo(source+destination+date);
    FirebaseRecyclerAdapter<Bus,BusViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Bus,BusViewHolder>(Bus.class,R.layout.bus_card,BusViewHolder.class,query) {
            @Override
            protected void populateViewHolder(BusViewHolder viewHolder,Bus model,int position) {
                viewHolder.setSource(model.getSource());
                viewHolder.setDestination(model.getDestination());
                viewHolder.setAvailable(model.getAvailable());
                viewHolder.setDate(model.getDate());
                viewHolder.setFare(model.getFare());
            }
        };
        recyclerView.setAdapter(firebaseRecyclerAdapter);
    

    Note that the last parameter in FirebaseRecyclerAdapter is query.