Reputation: 19
I am using this method to retrieve data on Android, and it always returns null. Inside the ondatachange
the listFinalBus
is not null, but when the return comes, I get a null value.
Here is my code:
public List<Bus> findAllBus() {
// Read from the database
myRef.child("Bus").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d(TAG, "onDataChange: " + dataSnapshot.toString());
for (DataSnapshot userDataSnapshot : dataSnapshot.getChildren()) {
Bus bus = userDataSnapshot.getValue(Bus.class);
Log.d(TAG, "onDataChange: after get value " + bus.getId().toString()+" nom "+bus.getNom().toString());
listFinalBus.add(bus);
Log.d(TAG, "onDataChange: list before return not null her" + listFinalBus.size());
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
Log.d(TAG, "onDataChange: list firas return" + listFinalBus.size());
//return is null
return listFinalBus;
}
Upvotes: 0
Views: 662
Reputation: 2357
Your .addValueEventListener(listener) works async. So you will return your field fisrt which is null and after the call is done, your listener get called. But your field is already returned. So to fix this, whether you write your own listener like:
interface MyCallback{
void onSuccess(List<Bus> bus)
}
and your code could be like:
public void findAllBus(MyCallback callback) {
// Read from the database
myRef.child("Bus").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d(TAG, "onDataChange: " + dataSnapshot.toString());
for (DataSnapshot userDataSnapshot : dataSnapshot.getChildren()) {
Bus bus = userDataSnapshot.getValue(Bus.class);
Log.d(TAG, "onDataChange: after get value " + bus.getId().toString()+" nom "+bus.getNom().toString());
listFinalBus.add(bus);
Log.d(TAG, "onDataChange: list before return not null her" + listFinalBus.size());
}
callback.onSuccess(List<Bus> bus);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
So you can get your List no matter where you like.And just implements the Callback and pass it to your repository.
Or if you familiar with RxJava. You can pass an Observable which gonna like
public Observable<Bus> findAllBus(){
return Observable.create(new ObservableOnSubscribe<Bus>() {
@Override
public void subscribe(ObservableEmitter<Bus> e) throws Exception {
myRef.child("Bus").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d(TAG, "onDataChange: " + dataSnapshot.toString());
for (DataSnapshot userDataSnapshot : dataSnapshot.getChildren()) {
Bus bus = userDataSnapshot.getValue(Bus.class);
Log.d(TAG, "onDataChange: after get value " + bus.getId().toString()+" nom "+bus.getNom().toString());
e.onNext(bus);
Log.d(TAG, "onDataChange: list before return not null her" + listFinalBus.size());
}
e.onComplete();
}
@Override
public void onCancelled(DatabaseError databaseError) {
e.onError(error);
}
}
});
}
Upvotes: 2