Retrieve data from firebase return null in onCreateView
Move your code inside onDataChange
as Firebase fetches data asynchronously
databaseTracks.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
Iterable<DataSnapshot> children = dataSnapshot.getChildren();
if (trackList != null) {
trackList.clear();
}
for (DataSnapshot c : children) {
trackList.add(c.getValue(UserFoodRecord.class));
}
if (trackList != null) {
for (UserFoodRecord u : trackList) {
dateList.add(u.getDate());
if (u.getDate() == todayDate) {
checkTodayRecord = true; //got today record
UserFoodRecord tempRecord = new UserFoodRecord(u.getDate(), u.getBreakfast(), u.getLunch(), u.getDinner(), u.getOther()
, u.getExercise(), u.getGoal(), u.getFood(), u.getExerciseBurn());
currentUserFoodRecord = tempRecord;
}
}
}
if (currentUserFoodRecord != null) {
caloriesGoal.setText(currentUserFoodRecord.getGoal().toString());
caloriesFood.setText(currentUserFoodRecord.getFood().toString());
caloriesExerc.setText(currentUserFoodRecord.getExerciseBurn().toString());
caloriesRemain.setText(currentUserFoodRecord.getRemaining().toString());
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
I get null when I try to access a variable from inner class in firebase methods
You cannot use something now that hasn't been loaded yet. With other words, you cannot simply use the username
outside the onDataChange()
method because it will always be null
due the asynchronous behaviour of this method. This means that by the time you are trying to print that result outside that method, the data hasn't finished loading yet from the database and that's why is not accessible.
A quick solve for this problem would be to use that results only inside the onDataChange()
method, otherwise I recommend you see the last part of my anwser from this post in which I have explained how it can be done using a custom callback. You can also take a look at this video for a better understanding.
String returns null after leaving child, when retrieving from firebase
That's because of async execution of the code, to fix it you'll have to wait for the execution. Like this:
void getData(String name, String dataToFetch) async{ // NOTE THE ASYNC HERE
//use await to wait for async execution
String value = await DBRef.child("dataToFetch").once().then((DataSnapshot dataSnapShot){
name = dataSnapShot.value;
print("one $name");
return name;
});
print("two $value");
}
UPDATE
If you call this method from the state of a StatefullWidget
this is how you should implement it:
class _MyHomePageState extends State<MyHomePage> {
String name; // this property will be updated by the getData
@override
void initState() {
super.initState();
getData(name, "theKeyYouWant"); // call getData in init state
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Test App'),
),
body: Text(name)
);
}
void getData(String paramName, String dataToFetch) async {
DBRef.child("dataToFetch").once().then((DataSnapshot dataSnapShot){
setState(() { // this will trigger the build method
name = dataSnapShot.value; // we update the new value.
});
});
}
}
Firebase - retrieving data by value to an outside variable
Firebase use callback methods to get the data from the server, In your case the return statement will be executed before the callback come from the Firbase. You can try to pass a callback method to your function and execute that when the callback from Firebase is triggered.
public static void checkIfBookmarked(final String title, callbackFunction){
final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
final DatabaseReference userBookmarks = FirebaseDatabase.getInstance().getReference().child("users")
.child(user.getUid()).child("bookmarks");
final boolean[] exists = new boolean[1];
userBookmarks.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
exists[0] = dataSnapshot.child(title).exists() ;
//execute your callback function here
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return;
}
Check this to see how to pass a function as parameter.
Passing function as a parameter in java
An alternative would be to move your code into OnDataChange method
Related Topics
Sqlite Connection Leaked Although Everything Closed
Android: Starting an Activity for a Different Third Party App
Android Dialog: Removing Title Bar
Error Building Android Library: Direct Local .Aar File Dependencies Are Not Supported
How to Create a Release Android Library Package (Aar) in Android Studio (Not Debug)
Android Animate Drop Down/Up View Proper
How to Get Preview in Composable Functions That Depend on a View Model
When Does Adt Set Buildconfig.Debug to False
Add Support Library to Android Studio Project
Are There Conventions on How to Name Resources
Error: This Android Sdk Requires Android Developer Toolkit Version 22.6.1 or Above
How to Get Canonical Id from Gcm
How to Animate a View in Android and Have It Stay in The New Position/Size
What Is Use of Cursor in Android Development
How to Add Network_Security_Config.Xml to Manifest in Expo App Without Ejecting