0

I'm trying to implement Firebase Database in my Android app, but when it give back the array which is supposed to be fill with the names of the strings, it is void. This is the function that I use to get back the names:

public class FirebaseOperation {

private static final String TAG1 = "Operacion de lectura";
FirebaseDatabase database = FirebaseDatabase.getInstance();
private final Callback callback;

public FirebaseOperation(Callback callback){
    this.callback = callback;
}

interface Callback{
    void dataIsLoaded(ArrayList<String> names);
}


public void  getUserNames(){
    final ArrayList<String> names = new ArrayList<>();

    DatabaseReference ref = database.getReference().child("idUsers");

    ref.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            for (DataSnapshot ds : dataSnapshot.getChildren()){
                String name = ds.getValue(String.class);
                names.add(name);
                Log.d(TAG1, "LEcturea correcta");
            }
            callback.dataIsLoaded(names);
        }
        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            Log.w(TAG1, "Error al leer los nombres de usuario");
        }
    });

}

}

And here is where i called it:

idusers = new ArrayList<>();
new FirebaseOperation(new FirebaseOperation.Callback() {
    @Override
    public void dataIsLoaded(ArrayList<String> names) {
          idusers = names;
}
}).getUsernames();
if(idusers.isEmpty()){
                Log.w(TAG, "Array VACIOOOOO");
            }

And it's supposed to return the ArrayList but when it returns is void, however in that function it enters in the onDataChange , so it's supposed to be Reading the values, but returns an empty array to the other class. Some ideas? I let you a capture of my database structure.

Database

Some ideas??

  • Check **[this](https://stackoverflow.com/questions/47847694/how-to-return-datasnapshot-value-as-a-result-of-a-method/47853774)** out. – Alex Mamo May 28 '19 at 10:07

1 Answers1

0

Because new ValueEventListener() is an asynchronous callback, this means the return nombres happens before the Firebase RTD has responded.

If you want to keep your class FirebaseOperation then you should have to use another callback to pass the Firebase once has been retrieved:

public class FirebaseOperation {

    private final Callback callback;

    //Initializing the callback on the constructor for simplicity
    public FirebaseOperaion(Callback callback) {
        this.callback = callback;
    }

    //It doesn't return
    public void getUserNames(){
    final ArrayList<String> names = new ArrayList<>();

    DatabaseReference ref = database.getReference().child("idUsers");

    ref.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            for (DataSnapshot ds : dataSnapshot.getChildren()){
                String name = ds.getValue(String.class);
                names.add(name);
                Log.d(TAG1, "LEcturea correcta");
            }
            callback.rtdResponse(names);
        }
        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            Log.w(TAG1, "Error al leer los nombres de usuario");
        }
        });
    }


    interface Callback {
        void rtdResponse(List<String> names);
    }

}

And now in the other class where you are using it, instead of

List<String> names = new FirebaseOperation().getUserNames();

You will have to use the callback:

//Use this if you want the other class implements the callback
new FirebaseOperation(this).getUserNames();
//Or use an anonymous implementation
new FirebaseOperation(new Callback {
    @Override
    void rtdResponse(List<String> names) {
        //Do something with your list here
    }
}).getUserNames();
cutiko
  • 9,887
  • 3
  • 45
  • 59
  • I have tried in your way and still empty, I will edit my question with your code, but now I know that is asynchronous thanks anyway!! –  May 27 '19 at 22:50