Reputation: 456
I am trying to build a separate class for firebase methods, one of these methods is to return an Object User
public User getUser(){
myRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.child("users").child(mUserID).child("user_info").getValue(User.class);
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.d(TAG, "onCancelled: Error: " + databaseError.getMessage());
}
});
return user;
}
returning the user gives me an error. is it possible to return the User user from the inner onDataChange() method? and how?
Upvotes: 1
Views: 73
Reputation: 191874
No, it's not possible because Firebase is asynchronous, and you're effectively trying to convert this method back into a blocking call by making the calling method "wait for" a returned object.
The appropriate pattern here is
1) make an interface.
public interface OnUserResult {
void onUser(User u);
}
2) pass interface into void method
3) pass result back to Callback interface
public void getUser(final OnUserResult callback) {
myRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.child("users").child(mUserID).child("user_info").getValue(User.class);
if (null!=callback) callback.onUser(user);
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.d(TAG, "onCancelled: Error: " + databaseError.getMessage());
}
});
}
4) Rewrite the calling method to not expect a returned object
// Bad: User user = api.getUser();
// Good
api.getUser(new OnUserResult() {
@Override public void onUser(User u) {
// Update the UI, or whatever
// Do not assign a global user variable here either
}
});
// any external user variable will (usually) still be null here
Libraries such as RxJava help you to implement this pattern in other ways
Upvotes: 3
Reputation: 55
Is user declared in the scope of the class? Because otherwise I don't know how getUser()
is accessing the user it is returning. Try declaring user in getUser()
instead of inside onDataChange
because the user in onDataChange
is only in the scope of that method.
Also, if onDataChange
is never called, there is never a declared User and it would return null
Upvotes: 0
Reputation: 218
It is not possible to return anything from an inner class.. But one can initialize an instance variable inside the inner class , making it accessible to all members of the class
Upvotes: 1