1

I have the following code that is supposed to read data from Firebase and add it to array lists namesList and addressList. I logged the values on onDataChange events. The logcat shows that data is infact read but when I iterate the list, it is of size zero. Can anyone please help me regarding this:

 @Override
public void onStart() {
    super.onStart();

    activeOrders = FirebaseDatabase.getInstance().getReference().child("Ordered Items");
    activeOrders.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {

            for (DataSnapshot child: snapshot.getChildren())
            {
                key = child.getKey().toString();

                name = FirebaseDatabase.getInstance().getReference().child("Users").child(key).child("name");

                address = FirebaseDatabase.getInstance().getReference().child("Users").child(key).child("shippingAddr");

                name.addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot snapshot) {
                        Log.i("Username", snapshot.getValue().toString());
                        namesList.add(snapshot.getValue().toString());
                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError error) {

                    }
                });

                address.addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot snapshot) {
                        Log.i("Address", snapshot.getValue().toString());
                        addressList.add(snapshot.getValue().toString());

                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError error) {

                    }
                });

            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {

        }
    });

    Toast.makeText(this, "Size:" + namesList.size(), Toast.LENGTH_SHORT).show();

    for(int i=0; i<namesList.size(); i++){
        Toast.makeText(this, namesList.get(i).toString(), Toast.LENGTH_SHORT).show();
    }

    logout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            signOutUser();
        }
    });
1
  • 2
    Please edit the question to show what you expect this code to do that's different than what you expect. It should also show the data you're trying to query. Without seeing the data, there's no way we can know if the query makes sense. Commented Jul 1, 2020 at 16:54

1 Answer 1

1

You are iterating the list in the main thread, while the actual list takes some time to come back from firebase, that is because all firebase callbacks runs in background thread inclusively

So, the below code runs in main thread before the actual data comes in

for(int i=0; i<namesList.size(); i++){
    Toast.makeText(this, namesList.get(i).toString(), Toast.LENGTH_SHORT).show();
}

And the below code runs in firebase background thread

public void onDataChange(@NonNull DataSnapshot snapshot) {
    Log.i("Username", snapshot.getValue().toString());
    namesList.add(snapshot.getValue().toString());
}

To solve this you can transfer the iteration as below

activeOrders.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot snapshot) {

        for (DataSnapshot child: snapshot.getChildren())
        {
            key = child.getKey().toString();

            name = FirebaseDatabase.getInstance().getReference().child("Users").child(key).child("name");

            address = FirebaseDatabase.getInstance().getReference().child("Users").child(key).child("shippingAddr");

            name.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot snapshot) {
                    Log.i("Username", snapshot.getValue().toString());
                    namesList.add(snapshot.getValue().toString());
                }

                @Override
                public void onCancelled(@NonNull DatabaseError error) {

                }
            });

            address.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot snapshot) {
                    Log.i("Address", snapshot.getValue().toString());
                    addressList.add(snapshot.getValue().toString());

                }

                @Override
                public void onCancelled(@NonNull DatabaseError error) {

                }
            });

        }
        
        
        for(int i=0; i<namesList.size(); i++){
            Toast.makeText(this, namesList.get(i).toString(), Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError error) {

    }
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.