0

I am trying to retrieve values from geoquery. The values are getting added to the map but when I return the values the map is empty. Here myPosition is my position Latlng values that I am using for my location. i have edited the question but still the problem is occuring the map is still empty

 private Map<String, GeoLocation> geoMap;
 public View onCreateView(LayoutInflater inflater, 
 ViewGroup container,  Bundle savedInstanceState) {
 View view=  inflater.inflate
(R.layout.fragment_new_search2,  container, false);

 geoMap= new HashMap<>();
    readdata(new MyCallback() {
        @Override
        public void onCallback(Map<String, 
        GeoLocation> geomap) {
        //    int size = geomap.size();
        }
    });
    int size = geoMap.size();
    Toast.makeText(getContext(), 
    String.valueOf(size), Toast.LENGTH_SHORT).show();
    return view;
    }


 private void readdata(final MyCallback myCallback){
 DatabaseReference ref = 
  FirebaseDatabase.getInstance().getReference()
  .child("WorkLocation");
    GeoFire geoFire = new GeoFire(ref);
    GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(myPosition.latitude, myPosition.longitude), 2);
    geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
        @Override
        public void onKeyEntered(String key, GeoLocation location) {
            geoMap.put(key,location);

        }

        @Override
        public void onKeyExited(String key) {

        }
        @Override
        public void onKeyMoved(String key, GeoLocation location) {
        }
        @Override
        public void onGeoQueryReady() {
        }
        @Override
        public void onGeoQueryError(DatabaseError error) {
        }
    });
    myCallback.onCallback(geoMap);

}

public interface MyCallback {
    void onCallback(Map<String, GeoLocation> geomap);
}     

I tried a toast inside onkeyentered the values are there and they are getting added but still, the values are not returning to the method and the size of the map is still zero.

Jimmy
  • 87
  • 2
  • 9
  • `addGeoQueryEventListener` callback methods are being invoked asynchronously – John O'Reilly Jun 15 '18 at 10:30
  • Possible duplicate of [How to return dataSnapshot value as a result of a method?](https://stackoverflow.com/questions/47847694/how-to-return-datasnapshot-value-as-a-result-of-a-method) – Alex Mamo Jun 15 '18 at 11:27
  • Please check the duplicate to see why do you have this behaviour and how can you solve this using a custom callback. – Alex Mamo Jun 15 '18 at 11:28
  • @AlexMamo i have changed the code but still the size is zero is there still anything wrong with the code – Jimmy Jun 15 '18 at 12:42
  • @JohnO'Reilly i have changed the code can you please check it again – Jimmy Jun 15 '18 at 12:42

1 Answers1

0

All code that requires the data to have been loaded, must be inside (or called from inside) the on... method. So:

 DatabaseReference ref = 
  FirebaseDatabase.getInstance().getReference()
  .child("WorkLocation");
    GeoFire geoFire = new GeoFire(ref);
    GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(myPosition.latitude, myPosition.longitude), 2);
    geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
        @Override
        public void onKeyEntered(String key, GeoLocation location) {
            geoMap.put(key,location);
            myCallback.onCallback(geoMap);
        }

        @Override
        public void onKeyExited(String key) { }
        @Override
        public void onKeyMoved(String key, GeoLocation location) { }
        @Override
        public void onGeoQueryReady() { }
        @Override
        public void onGeoQueryError(DatabaseError error) { }
    });

}

If you only want your onCallback to be invoked once all initial keys have been loaded through Geofire, put it in onGeoQueryReady:

 DatabaseReference ref = 
  FirebaseDatabase.getInstance().getReference()
  .child("WorkLocation");
    GeoFire geoFire = new GeoFire(ref);
    GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(myPosition.latitude, myPosition.longitude), 2);
    geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
        @Override
        public void onKeyEntered(String key, GeoLocation location) {
            geoMap.put(key,location);
        }

        @Override
        public void onKeyExited(String key) { }
        @Override
        public void onKeyMoved(String key, GeoLocation location) { }

        @Override
        public void onGeoQueryReady() {
            myCallback.onCallback(geoMap);
        }

        @Override
        public void onGeoQueryError(DatabaseError error) { }
    });

}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • thanks a lot, is there any way i can loop through the map even if i put it inside onKeyEntered. i have asked it in another question can you please have a look at it https://stackoverflow.com/questions/50877806/valueeventlistener-inside-for-loop – Jimmy Jun 15 '18 at 14:48
  • can you please look at it now i want to paginate the recycler view , i am confused as to how to do it if i have a map which contains the keys . it means i have to paginate the entries in map now but i am confused as to how to do it – Jimmy Jun 15 '18 at 15:41
  • GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(myPosition.latitude, myPosition.longitude), 2); here in my readData method i am passing my values on predefined lattitude and longitude. how do i add a variable in this readData method – Jimmy Jun 16 '18 at 21:27