Reputation: 259
I want to receive a string from addValueEventListener()
method I use to resell the data from the database Firebase. The data arrive correctly.
But when certain to get the string out of that method to use it in another, it returns nothing.
You have tips?
I already tried putExtras and also create a method on purpose but it did not work.
final DatabaseReference mPostReference = FirebaseDatabase.getInstance().getReference().child("user-daily").child(getUid()).child("2017-Year");
mPostReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
final ArrayList<String> labels = new ArrayList<String>();
for (DataSnapshot data : dataSnapshot.getChildren()){
final DailyItem dailyItem = data.getValue(DailyItem.class);
labels.add(dailyItem.mese);
}
title.setText(labels.get(position));
a = title.getText().toString();
}
@Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(view.getContext(),"database error",
Toast.LENGTH_SHORT).show();
}
});
//this return null... why?
String title = a;
Upvotes: 3
Views: 10306
Reputation: 1
This is a trick which does it. It would be easy to do so if you have less data to retrieve from ValueEventListener.
Inside the onDataChange()
, use a setText to set the required value in it. Keep the visibility of this text view as "Gone". Then retrieve using getText outside the ValueEventListener.
Upvotes: 0
Reputation: 11
In order to retrieve the string from method addValueEventListener
in viewmodel or any other network call, it is recommended to use the either MutableLiveData<T>
or LiveData<T>
and observe the same in your activity. Observer will observe the changes, and as soon as string got filled up, the observer method will automatically give you string which you are looking.
You need to create reference variable for the LiveData<T> reference_variable
wherever your addValueEventLister
is located and set its value in your addValueEventListener
.
And then in your viewmodel create the returning value function like below... Observe this function in your activity and you will have your string.
public MutableLiveData<TotalRunsWicketsAndData> getDisplayableDetails() {
return observableLiveData;
}
I am using MutableLiveData
here.
Upvotes: 0
Reputation: 598728
The data is loaded from Firebase asynchronously. By the time you run title = a
, the onDataChange
method hasn't been called yet. Set some breakpoints in a debugger to verify this, it's key to understanding how asynchronous loading works.
The solution is to reframe your problem from "first get the object, then do blabla with the title" to "start getting the object; once the object is available, do blabla with the title".
In code this translates to:
final DatabaseReference mPostReference = FirebaseDatabase.getInstance().getReference().child("user-daily").child(getUid()).child("2017-Year");
mPostReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
final ArrayList<String> labels = new ArrayList<String>();
for (DataSnapshot data : dataSnapshot.getChildren()){
final DailyItem dailyItem = data.getValue(DailyItem.class);
labels.add(dailyItem.mese);
}
title.setText(labels.get(position));
// Do blabla with the title
String title = title.getText().toString();
}
@Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(view.getContext(),"database error",
Toast.LENGTH_SHORT).show();
}
});
Many developers new to Firebase (and other modern web APIs, as they all work this way) struggle with this problem. So I recommend you also check out their questions and answers:
Upvotes: 5
Reputation: 594
You can retrieve the whole list by using GenericTypeIndicator. Follow the official guide on here
Upvotes: -1