fbm fatma
fbm fatma

Reputation: 450

can't get values out of ondatachange method

I'm currently developing an android app where I'm using firebase as database but when in got the variable in the onDataChange method and I assign them to a global variables I got null variables but when I call those variables in the onDataChange method they are not null.

public class PositionateMarkerTask extends AsyncTask {
    public ArrayList<Location> arrayList= new ArrayList<>();
    public void connect() {
        //setting connexion parameter
        final Firebase ref = new Firebase("https://test.firebaseio.com/test");
        Query query = ref.orderByChild("longitude");

        //get the data from the DB
        query.addListenerForSingleValueEvent(new ValueEventListener() {

            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                //checking if the user exist
                if(dataSnapshot.exists()){
                    for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
                        //get each user which has the target username
                        Location location =userSnapshot.getValue(Location.class);
                            arrayList.add(location);
                        //if the password is true , the data will be storaged in the sharedPreferences file and a Home activity will be launched
                    }
                }
                else{
                    System.out.println("not found");
                }
            }

            @Override
            public void onCancelled(FirebaseError firebaseError) {
                  System.out.println("problem ");

            }
        });
    }

    @Override
    protected Object doInBackground(Object[] params) {
        connect();
        return null;
    }

    @Override
    protected void onPostExecute(Object o) {
        super.onPostExecute(o);

        System.out.println("the firs long is"+arrayList.get(0).getLongitude());

    }
}

Upvotes: 3

Views: 7157

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 600116

Welcome to asynchronous programming, which messes up everything you always thought was true. :-)

Firebase retrieves/synchronizes with the database automatically in the background. The work happens on a separate thread, so you don't need and AsyncTask. But unfortunately this also means you can't wait for the data.

I typically recommend that you reframe your code from "first do A, then to B" to "whenever we get A, we do B with it".

In your case, you want to get the data and then print the longitude of the first item. Reframed that is: whenever you receive data, print the longitude of the first item.

Query query = ref.orderByChild("longitude");

query.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        if(dataSnapshot.exists()){
            for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
                Location location =userSnapshot.getValue(Location.class);
                arrayList.add(location);
            }
            System.out.println("the first long is"+arrayList.get(0).getLongitude());                }
        else{
            System.out.println("not found");
        }
    }

    @Override
    public void onCancelled(FirebaseError firebaseError) {
          System.out.println("problem ");
    }
});

A few things to note here:

  1. if you're only interested in the first item, you can limit the query to one item: query = ref.orderByChild("longitude").limitToFirst(1). This will retrieve less data.

  2. I recommend using addValueEventListener() instead of addListenerForSingleValueEvent(). The former will keep synchronizing the data. This means that if you insert/change the longitude of an item in the list, your code will automatically get retriggered and print the (potentially) new first item.

Upvotes: 9

Related Questions