atimetoremember
atimetoremember

Reputation: 133

Firebase addListenerForSingleValueEvent excute later in loop

This's my code, i don't know why the loop finished, then addListenerForSingleValueEvent start excute, what did i do wrong???

firebase.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {



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


                fb.addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot xdataSnapshot) {

                       Toast.makeText(getApplicationContext(), "YYYYYYY", Toast.LENGTH_LONG).show();
                    }

                    @Override
                    public void onCancelled(FirebaseError firebaseError) {

                    }
                });
                Toast.makeText(getApplicationContext(), "XXXXXX", Toast.LENGTH_LONG).show();


            }

        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {

        }
    });

The loop is 3 time and The result of above code is Toast XXXXX apear 3 time and then Toast YYYYYYY apear 3 time, why???? i want to Toast YYYYY and then Toast XXXXX and again 3 time.

Upvotes: 0

Views: 3678

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598765

When you call addListenerForSingleValueEvent() you start loading the referenced data from the Firebase servers. This may take some time, which is why you pass in a callback ValueEventListener object. When the data is available, Firebase will call its onDataChange() methods.

So what happens initially is:

    app                 Firebase
                         Server

        --Get item 1-->
        --Get item 2-->
        --Get item 3-->

Now the Firebase servers need some time to get these items for you. They may need to be loaded from disk or at the very least, there may be quite some distance between the app and the servers.

In the meantime your app continues running and executes the line right you attach the listener:

Toast.makeText(getApplicationContext(), "XXXXXX", Toast.LENGTH_LONG).show();

This executes three times, so you see three XXXXXX toasts.

By now the data is probably coming back from the Firebase servers into the app:

    app                 Firebase
                         Server

        <--  Item 1  --
        <--  Item 2  --
        <--  Item 3  --

And for each of these your code shows a YYYYYYY toast.

The use-case with the toasts makes little sense to me. But you can accomplish it by looping over the children twice:

firebase.addValueEventListener(new ValueEventListener() {
  public void onDataChange(DataSnapshot dataSnapshot) {
    for (DataSnapshot itemDataSnapshot : dataSnapshot.getChildren()) {
      Toast.makeText(getApplicationContext(), "XXXXXX", Toast.LENGTH_LONG).show();
    }
    for (DataSnapshot itemDataSnapshot : dataSnapshot.getChildren()) {
      fb.addListenerForSingleValueEvent(new ValueEventListener() {
        public void onDataChange(DataSnapshot xdataSnapshot) {
          Toast.makeText(getApplicationContext(), "YYYYYYY", Toast.LENGTH_LONG).show();
        }
        public void onCancelled(FirebaseError firebaseError) {}
      });
    }
  }
  public void onCancelled(FirebaseError firebaseError) {
  }
});

Upvotes: 3

Related Questions