Filtering geoFire requests by specific criteria before populating viewHolder in Android

I have successfully applied geoFire to get the record keys from the main firebase node in the custom area.

Then I tried to store those keys in a new unique node so I can use them later to populate the viewHolder as this seems to be the best practice.

The problem is, I don't want all the objects stored in the unique node to actually populate the viewHolder; I only want a subset of them.

If I filter inside the populateViewHolder method for example

@Override
public void onDataChange(DataSnapshot dataSnapshot) {
    SwarmReport retrievedModel = dataSnapshot.getValue(SwarmReport.class);
    if(!retrievedModel.isClaimed()){
        viewHolder.bindSwarmReport(retrievedModel);
    }
}

      

I am getting some items in the viewHolder that are empty.

If instead I try to filter before setting up the FirebaseAdapter eg. in my addGeoQueryEventListener methods, I have to add addListenerForSingleValueEvent

to check the criteria by which I want to filter:

public void onKeyEntered(String key, GeoLocation location) {
    claimCheckKey = key;
    final DatabaseReference claimCheckRef = FirebaseDatabase.getInstance().getReference("all").child(key);
    claimCheckRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            SwarmReport claimCheckSwarmReport = dataSnapshot.getValue(SwarmReport.class);
            if (!claimCheckSwarmReport.isClaimed()){
                swarmReportIds.add(claimCheckKey);
            }
        }

      

Seems to onGeoQueryReady

run before completion addListenerForSingleValueEvent

in onKeyEntered

. Any advice on how to get onGeoQueryReady

to wait for the entire swarmReportIds.add (ClaimCheckKey) command to complete?

In case it's helpful, here's a snapshot of my firebase structure: enter image description here

+3


source to share


1 answer


I don't really understand what you are trying to achieve, but I'll guess and say that you not only want the closest key

, but also want to filter the closest key

based on some other criteria, like the closest restaurant, then prices.

The workaround I did for this (still looking for better options) is to set a flag inside the method onDatachange

I called inside the method onKeyentered

that compares the records inside the node, (for the sake of the argument, we'll say prices)

UPDATE

  @Override
        public void onKeyEntered(final String key, GeoLocation location) {
     final DatabaseReference db = FirebaseDatabase.getInstance().getReference("<your ref>"+key);
     db.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {


                    for (DataSnapshot ds : dataSnapshot.getChildren()) {


                        String dishPrice=ds.getValue(String.class);
                        int price=Integer.parseInt(dishPrice);



                            if (price<=12) {

                                isMatch=true;

                            }


                    }
                    if(isMatch){
                        getRestaurants(key);
                    }
                    isMatch=false;


                }

      

And outside for each loop, onDatachange

I decided to execute a function that fills arraylist

mine adapter

only when the function is true



getRestaurants method

    private void getRestaurants(final String id) {

   final DatabaseReference temp=FirebaseDatabase.getInstance().getRef("<your 
 ref>"+id)
          temp.child(id).addListenerForSingleValueEvent(new 
          ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {


                    Restaurant restaurant = dataSnapshot.getValue(Restaurant.class);  
                    restaurant.setName(restaurant.getName());
                    restaurant.setImageUri(restaurant.getImageUri());
                    restaurant.setUid(id);


                    //add elemens to arraylist


                        resList.add(restaurant);
                        adapter.notifyDataSetChanged();


                }

      

Another suggestion is to make a function in the cloud (assuming again) in your case that all you need is to check if the value of the "declared" changes changes, so you can set an event trigger onUpdate

or onWrite

and check the value in onChanged()

and get the current value (true / false), after which you can use geoFire requests and get closure by users and update their nodes based on the value.

Event triggers

Cloud functions

+4


source







All Articles