Reputation: 437
I have the stored a User at the Firebase's database. When I want to retrieve the user it is null and I can't explain myself why. My User class simply consists of an String
'email' and String
'name' and boolean
'firstAppUse'.
So I wrote the following method to retrieve a user from database:
public static User getUser(){
final User [] user = new User[1];
DatabaseHelper.userDB.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
user[0] = dataSnapshot.getValue(User.class);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return user[0];
}
Narrow all expectations user[0]
is null. Although the element exists in the database and the reference to it in DatabaseHelper.userDB
is just fine:
public class DatabaseHelper {
private static FirebaseDatabase database = FirebaseDatabase.getInstance();
public static DatabaseReference userDB = database.getReference("users/" + FirebaseAuth.getInstance().getCurrentUser().getUid());
} Does anybody see the issue? Thanks in advance.
Upvotes: 0
Views: 1621
Reputation: 1167
When you fetch data from firebase, it is an Asynchronous Task. If you call getUser() and return user[0] then it will always return null because before getting results (DataSnapshot
) from firebase you have returned the function.
Here is the code,
public static void getUser(Handler.Callback callback){
DatabaseHelper.userDB.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
User userObj = dataSnapshot.getValue(User.class);;
Message message = new Message();
Bundle bundle = new Bundle();
bundle.putSerializable("user",userObj); //Make sure that user object is serialisable
message.setData(bundle);
callback(message);
}
@Override
public void onCancelled(DatabaseError databaseError) {
Message message = new Message();
Bundle bundle = new Bundle();
bundle.putSerializable("user",null);
message.setData(bundle);
callback(message);
}
});
}
Here is how you should call this function:
getUser(new Handler.Callback(){
@Override
public boolean handleMessage(Message message) {
if(message != null){
User user = (User)message.getData().get("user");
//Do whatever you want with "user" object
}
return false;
}
});
This will make your code modular. You can call this function anywhere in your code to get user object and you can keep all your firebase database listener code in a single place for separation of database layer and logic layer.
Upvotes: 0
Reputation: 1211
user[0] will always be null because firebase database is asynchronous
// in userdb it should be like this
// database.child("users").child("uid")
private User mUser = null;
public void getUser(){
DatabaseHelper.userDB.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if dataSnapshot.exists(){
mUser = dataSnapshot.getValue(User.class);
// do something with user
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Upvotes: 1
Reputation: 1925
Firebase database is async,
When the code gets into the 'return' line, the block of code in the 'onDataChange' callback didn't executed
Please, read that article to learn more about async and sync methods
Upvotes: 1