Null Pointer when trying to retrieve user details from Firebase Realtime Database

Viewed 83

In my Android app, I have a database repository to contact Firebase Realtime Database and a service layer with some methods. My SaveUserProfile method works but I keep getting a null pointer on my GetUserFromUid.

The 'user' object it returns is null and I don't know why. The node in my DB is called "users" (all lowercase) and I want to retrieve a user as a model via their userId and display the name and email onscreen.

Can anybody see where I'm going wrong?

My DbContext:

public class DbContext implements IDbContext {

User user = null;
Context context;
DatabaseReference databaseUsers = FirebaseDatabase.getInstance().getReference("users");

 public DbContext(Context context){
   super();
   this.context = context;
}

@Override
public void AddUserAccount(User user1) {
    databaseUsers.child(user1.userId).setValue(user1);
}

@Override
public User GetUserFromFirebase(String uid) {
   databaseUsers.child(uid)
           .addListenerForSingleValueEvent(new ValueEventListener() {
               @Override
               public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                   user = dataSnapshot.getValue(User.class);
               }

               @Override
               public void onCancelled(@NonNull DatabaseError databaseError) {

               }
           });
    return user;
}

My DbService:

public class DbService implements IDbService {

//instance of DbContext for firebase handling
private DbContext dbContext;

public DbService(Context context){
    super();
    dbContext = new DbContext(context);
}

@Override
public User SaveUserProfile(User u) {

    dbContext.AddUserAccount(u);

    return u;
}

@Override
public User GetUserFromUid(String uid) {
    User user = dbContext.GetUserFromFirebase(uid);
    return user;
}

My User model:

public class User {

public String userId;
public String name;
public String email;
public String account;

//constructor required for calls to DataSnapshot.getValue(User.class)
public User(){
}

public User(String userId, String name, String email, String account) {
    this.userId = userId;
    this.name = name;
    this.email = email;
    this.account = account;
}

public String getUserId() {
    return userId;
}

public void setUserId(String userId) {
    this.userId = userId;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

public String getAccount() {
    return account;
}

public void setAccount(String account) {
    this.account = account;
}

My activity where I want to display the users' details:

public class DetailsActivity extends AppCompatActivity {
//tag
private static final String TAG = DetailsActivity.class.getSimpleName();

//firebase auth
private FirebaseAuth mAuth;

//variables
private TextView inputName, inputEmail;
private DatabaseReference mFirebaseDatabase;
private String userId;
public String currentUserAccount;
public String teacherAccountNav = "Teacher";
public User userDetails;

@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_details);

    inputName = findViewById(R.id.nameTextView);
    inputEmail = findViewById(R.id.emailTextView);

   

    FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();

    assert user != null;
    userId = user.getUid();

   
    getUserDetails(userId);
    inputName.setText(userDetails.name);
    inputEmail.setText(userDetails.email);
}

public User getUserDetails(String uid){
    DbService dbService = new DbService(this);
    userDetails = dbService.GetUserFromUid(uid);
    return userDetails;
}

EDITS BELOW

My callback:

public interface Callback {
void myResponseCallback(User user);
}

My EDITED DbContext:

public class DbContext implements IDbContext {

User user = null;
Context context;
DatabaseReference databaseUsers = FirebaseDatabase.getInstance().getReference("users");

public DbContext(Context context) {
    this.context = context;
}

@Override
public void AddUserAccount(User user1) {
    databaseUsers.child(user1.userId).setValue(user1);
}

@Override
public void GetUserFromFirebase(String uid, final Callback callback) {
    databaseUsers.child(uid)
            .addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    user = dataSnapshot.getValue(User.class);
                    callback.myResponseCallback(user);
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {

                }
            });

}

My EDITED DbService:

public class DbService implements IDbService {

//instance of DbContext for firebase handling
public DbContext dbContext;

public DbService(Context context){
    super();
    dbContext = new DbContext(context);
}

@Override
public User SaveUserProfile(User u) {

    dbContext.AddUserAccount(u);

    return u;
}

@Override
public User GetUserFromUid(String uid) {
    final User[] user1 = {new User()};
    dbContext.GetUserFromFirebase(uid, new Callback() {
        @Override
        public void myResponseCallback(User user) {
            user1[0] = user;
        }
    });
    return user1[0];
}

My EDITED Activity:

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_details);

    inputName = findViewById(R.id.nameTextView);
    inputEmail = findViewById(R.id.emailTextView);

    FirebaseDatabase mFirebaseInstance = FirebaseDatabase.getInstance();

    //reference to 'users' node
    mFirebaseDatabase = mFirebaseInstance.getReference("users");

    FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();

    assert user != null;
    userId = user.getUid();


    getUserFromFirebase(userId);

}

public void getUserFromFirebase(String uid){
    userDetails = (new DbService(this)).GetUserFromUid(uid);
    inputEmail.setText(userDetails.email);
    inputName.setText(userDetails.name);
}

Debug BEFORE edits:

debug before edits

Debug AFTER edits:

debug after edits

As you can see from the debug, before the callback interface, userDetails was null. After the interface implementation, userDetails is not null but all of the object values are null. I don't know why this is as they are filled in the database. Any ideas?

0 Answers
Related