Reputation: 159
I am trying to fetch the user details of a particular user using his UID. I need a method that can return the userName as a String type so that I can store it and display it in my app.
getUserName("UID");
This is how my database looks like -
This is what i tried doing -
private String getUserName(String startedBy) {
mProfileRef=database.getReference("Profile").child(startedBy).child("UserDetails").child("userName");
mProfileRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
userName = dataSnapshot.getValue(String.class);
Log.i(TAG, "onDataChange: "+userName);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return userName;
}
The Log statement executes perfectly and gives the correct userName based on the UID. The method does not return the userName. It returns null. How do I return the userName?
Upvotes: 0
Views: 55
Reputation: 3527
You can directly update your view inside the call back for firebase database read given your firebase code is also in the same class.
private void getUserName(String startedBy, TextView textView) {
mProfileRef=database.getReference("Profile").child(startedBy).child("UserDetails").child("userName");
mProfileRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
userName = dataSnapshot.getValue(String.class);
textView.setText(userName);
Log.i(TAG, "onDataChange: "+userName);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
The answer from Waqas Pervez is also a very good solution.
Upvotes: 0
Reputation: 2430
It is because Firebase
operations are performed asynchronous. That means the method onDataChange
executes on a background thread meanwhile your UI thread executes the original method and returns the value without waiting for the Firebase
response.
The solution can be done with using an interface.
1 - Define an interface
public interface OnDataLoaded {
onDataLoaded(String username);
}
2 - Pass the interface as the method argument
public void getUserName(String startedBy, OnDataLoaded onDataLoaded)
3 - Use the interface to pass the username.
mProfileRef = database.getReference("Profile").child(startedBy).child("UserDetails").child("userName");
mProfileRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
userName = dataSnapshot.getValue(String.class);
onDataLoaded.onDataLoaded(username);
Log.i(TAG, "onDataChange: "+userName);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
4 - Use the interface in your Activity/Fragment.
public class yourActivity implements OnDataLoaded
5 - You control will be transfered to you activity method onDataLoaded
@Override
public void onDataLoaded(String userName) {
// your userName will be available here.
// you can use your bindings here.
}
NOTE : wrote with without any IDE. Might contain some syntax errors.
Upvotes: 3