Retrieve String out of addValueEventListener Firebase
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:
- Cannot access firebaseObjectObservable outside of set
- Android Firebase get value of child without DataChange
- Value of a global variable is reset after it is initialised in ValueEventListener
- can't get values out of ondatachange method
- ArrayList not updating inside onChildAdded function
- Setting Singleton property value in Firebase Listener
- and most others in this list of search results
How to get the string values from a query inside a for loop being used for an addValueEventListener
Data from Firebase is only available inside the onDataChange
method, or in code called from there. There is no workaround for this.
If you require an additional database call to load additional data, you should:
- either hold off adding the item to the list at first, and then only add it in the inner
onDataChange
- or add the incomplete item to the list at first, and then update it in the inner
onDataChange
So the simplest fix is to do the first, which looks something like this:
query.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
rank = "" + dataSnapshot1.child("rank").getValue();
profilePicture = "" + dataSnapshot1.child("image").getValue();
username = "" + dataSnapshot1.child("username").getValue();
chatsItemArrayList.add(new ChatsItem(getProfilePicture(), title, date, speaks, description, getUsernameText(), getRankText(), upvotes, views, picture));
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
});
You'll typically want to also refresh the adapter in that inner onDataChange
method by calling something like adapter.notifyDataSetChanged()
.
Also see:
- getContactsFromFirebase() method return an empty list
- Wait Firebase async retrieve data in Android
- Only load layout when firebase calls are complete
- and many more from this list
not be able to retrieve firebase data using addValueEventListener
I think its nested too much but to answer your question, you need to remove this from your code:
dealList.clear();
and add it outside of the addValueEventListener()
like this:
protected void onStart() {
super.onStart();
dealList.clear();
rootRef.addValueEventListener(new ValueEventListener() {
Edit:
@Override
protected void onStart() {
super.onStart();
dealList.clear();
rootRef.child(expertId).child("Cooker Deals").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot dealSnapshot : dataSnapshot.getChildren()){
for(DataSnapshot datas : dealSnapshot.getChildren(){
NewDeal_Database info = datas.getValue(NewDeal_Database.class);
dealList.add(info);
}
DealList adapter = new DealList( New_Deal_List.this,dealList);
lvDealList.setAdapter(adapter);
adapter.notifydatasetchanged();
}
Data being lost after addValueEventListener Firebase Android
The line
Log.d("after","valu" + newDay.toString());
is calling before firebase gets result from database.
All you need to do is create a method
public void printResult(){
Log.d("after","valu" + newDay.toString());
}
Now call this method as
newDay = new ArrayList<Integer>();
mUserDatabase.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
newDay.addAll((ArrayList<Integer>)dataSnapshot.getValue());
Log.d("newday", "onDataChange:"+newDay.toString());
printResult();
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
Reason
Firebase has it's own async mechanism like volley library onDataChange function will be call when firebase gets some result from internet and execute the below code as normally in your case below code is your Log.d("after","value"+newDay.toString()); line.
Hope this will help you.
how to retrieve data from fire base and assign to a string
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
mDatabase.child("menu").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
//This will loop through all items. Add variables to arrays or lists as required
for (DatasnapShot snap : dataSnapshot.getChildren())
{
foodname = dataSnapshot.child("name").getValue().toString();
String prize = dataSnapshot.child("prize").getValue().toString();
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
You can fetch each child individually like such. Or you can make use of a Model or a Hashmap to fetch all of the data and then fetch the data you would like based on the Key
Retrieving data in firebase database without calling addValueEventListener
Firebase api is asynchronous meaning that when you use AddValueEventListener
to retrieve data from the database, the program will not stop and continue executing. Therefore in this log
:
Log.i("Original_Quantity", ""+originalQuantity);
You will get null since it is executed before the data is fully retrieved. There are two ways to access the data either inside the onDataChange
or you can do the following:
How to return DataSnapshot value as a result of a method?
Related Topics
Error: Failed to Resolve: Com.Android.Support:Appcompat-V7:29.0.1'
Navigation Drawer with Backword Compatibility Android
Can't Get File Uri from Intent Onactivityresult
Save Data and Change Orientation
How to Read Contacts in Android Using Realm
How to Decompile an APK or Dex File on Android Platform
How to Change Color of Android Listview Separator Line
Best Ocr (Optical Character Recognition) Example in Android
Streaming Audio from a Url in Android Using Mediaplayer
How to Use the Android Volley API
Android Phone Orientation Overview Including Compass
Are Parameters in Strings.Xml Possible
How to Record Screen and Take Screenshots, Using Android API
How to Create Context Menu for Recyclerview
Certpathvalidatorexception:Trust Anchor for Certificate Path Not Found - Retrofit Android
Gridlayout and Row/Column Span Woe