0

I am querying nearby locations using Firebase and the results are correct when I do a systemPrint. But when I tried to create a new Location item and put it in a globally declared arrayList then loop through the ArrayList to print it. It doesn't print. I tried something similar with a hashset where I declare a global hashset and tried adding the id and geolocation to it, then loop through it, it didn't print.

This is the printout when I do a systemPrint:

03-05 21:42:16.225 12604-12604/? I/System.out: aa6b6c55-40da-416e-bbc0-626f10d2db80 51.02878131 -114.13542057
03-05 21:42:16.262 12604-12604/? I/System.out: 1f682c8b-be9a-4310-aa92-216f041f0547 51.02933723 -114.13514678
03-05 21:42:16.262 12604-12604/? I/System.out: 707a5af3-8fa0-4f69-b88f-593a0acd3ee8 51.02933723 -114.13514678

I set this arrayList globally

List<Locations> locationList;


in onCreate(){
......
locationList = new ArrayList<>();
......
}



 geoFire = new GeoFire(new Firebase("https://xyz.firebaseio.com/locations/"));

        GeoLocation center = new GeoLocation(location.getLatitude(), location.getLongitude());
 final HashSet hs = new HashSet();
        GeoQuery geoQuery = geoFire.queryAtLocation(center, 5);
        geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
            @Override
            public void onKeyEntered(String username, GeoLocation location) {

                System.out.println(username + location.latitude + location.longitude);

                Locations eachLocation = new Locations();
                eachLocation.setId(username);
                eachLocation.setLatitude(String.valueOf(location.latitude));
                eachLocation.setLongitude(String.valueOf(location.longitude));

                locationList.add(eachLocation);


//
//                }

            }

            @Override
            public void onKeyExited(String username) {
                usersNearby.remove(username);
                // additional code, like removing a pin from the map
                // and removing any Firebase listener for this user
            }
            @Override
            public void onKeyMoved(String s, GeoLocation geoLocation) {

            }

            @Override
            public void onGeoQueryReady() {

            }

            @Override
            public void onGeoQueryError(FirebaseError firebaseError) {

            }
        });

    for (Locations x: locationList){
        Log.i("eachLocation", x.getId() + x.getLatitude() + x.getLongitude());
    }
System.out.println(hs);

This is my Locations class

public class Locations {
    String id;
    String latitude;
    String longitude;

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getLatitude() {
    return latitude;
}

public void setLatitude(String latitude) {
    this.latitude = latitude;
}

public String getLongitude() {
    return longitude;
}

public void setLongitude(String longitude) {
    this.longitude = longitude;
}

}

*****UPDATE - I am also noticing another pattern where I can not perform function inside another Firebase query****

I declared a global userCountry variable, userCountry, and then I run a query to obtain the user's country that is saved. Inside the function, it logs fine. But when i try to set the country value to userCountry, and log it outside of the query, my app crashes and errors out on a NullPointerException. I need to set userCountry globally so I can feed it into another query as a parameter.

String userCountry;


 ref = new Firebase("https://xyzChat.firebaseio.com/users/" + intent.getStringExtra("userId") + "/country");

    Query queryRef = ref.orderByChild("country");

        queryRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                Log.i("userCountry", String.valueOf(dataSnapshot.getValue()));
                userCountry = String.valueOf(dataSnapshot.getValue());
            }

Log.i("secondUserCountry", userCountry);

Ben Wong
  • 691
  • 2
  • 19
  • 29
  • You mean to say the for loop `for (Locations x: locationList){` is not printing the items? – Abdullah Mar 06 '16 at 03:27
  • @Abdullah, yes it's the loop that is not printing. – Ben Wong Mar 06 '16 at 03:38
  • You get the data in `onKeyEntered` which will be called after sometime and you print the list immediately after you set the `GeoQueryEventListener`. The call is asynchronous. – Abdullah Mar 06 '16 at 03:46
  • @Abdullah in onKeyEntered, the call should be called immediately per the doc - https://github.com/firebase/geofire-java, if "The location of a key now matches the query criteria." And since the locations I have stored are in my search criteria, it should be called right away. When I did systemPrint, it printed. But it won't load into my ArrayList. – Ben Wong Mar 06 '16 at 04:05
  • Do you check logcat..the item in the for loop should be printed in the logcat.. – Sanket Kumar Mali Mar 06 '16 at 04:19
  • @SanketKumarMali As mentioned, SystemPrint prints fine (I updated the post to show) with the results I expected. It's just that the results won't load into the arrayList, and print after. – Ben Wong Mar 06 '16 at 04:43
  • locationList = new ArrayList<>(); I think it should be, locationList = new ArrayList(); – Sanket Kumar Mali Mar 06 '16 at 05:26

2 Answers2

1

Events are fired asynchronously in GeoFire. So at the time you print out the locationList it will still be empty. You will need to wait until onGeoQueryReady is called until all elements have been added. If you move the logging code into there, it should print all locations. Note that onGeoQueryReady is called every time you update the query.

jonnydee
  • 1,311
  • 1
  • 7
  • 11
-1

Override toString () method in "Location" class.. Add this code in "Location" class..

 @override
public String toString ()
{
    Return "id:"+this.getId ()+",  Latitude:"+this.getLatitude ()+",  Langitude:"+this.getLangitude ()+"\n";
}

Now change your code..Remove the loop..instead of this code

Log.i("eachLocation", x.getId() + x.getLatitude() + x.getLongitude());

Just use..

Log.i ("eachLocation",hs);

Now your code should works fine...