I want to build a method that returns a child
value in FireBase
. I tried to do something like this:
public String getMessage(){
root.child("MessagesOnLaunch").child("Message").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
message = (String) dataSnapshot.getValue();
Log.i("4r398", "work");
}
@Override
public void onCancelled(FirebaseError firebaseError) {
Log.e("error", firebaseError.getMessage());
}
});
return message;
}
The problem is that the method returns null
that is probably because the method doesn't wait until the listener finishes and return null
because its the default value of message
.
How can I make this method wait until the listener occurs and then return the value.
Don't use Firebase as functions that return values - it goes against it's asynchronous nature.
Plan code structure that allows Firebase to perform it's task and then within the closure (block) go to the next step.
In your code, for example, change the function to not return anything and within the onDataChange, as the last line call the next function to update your UI.
Make an interface
Declare the following function readData()
Call the readData() function as follows
readData() can be called inside your getMessage() method or even inside onCreate()
You can follow this link https://youtu.be/LVaIArVY52U
Firebase database is quite slow when retrieving the data so to make the application wait for the process to complete you can follow this
Create a new class Ex. Firebasedata.java and extent it with Application and add put this code in the OnCreate sections
declare the java class in the manifests
Then go back to the class where you want to get the data and create a dialog with this code
You can look into the link above and get a better idea
Sorry to be a little late to this party but rather than have firebase return a value you could set up an observer / view model, then when you run your async firebase function the onData method is called from this you would update your view models data which then triggers its onDataChanged method which you can then update your layout from
I'll leave this here to help anyone who faces the same problem as me. @Tirupati Singh code looks nice but I wrote my answer below his why it didn't work for me. Using Atomic type worked -
Note the function can only return message type Integer. I couldn't get it to work for String as no Atomic type for String. Hope this helps!
You can use CountDownLatch. This is how you can use it.