Java 尝试从Firebase实时数据库检索用户详细信息时使用空指针
在我的Android应用程序中,我有一个数据库存储库来联系Firebase实时数据库,还有一个服务层,提供一些方法。我的SaveUserProfile方法可以工作,但我在GetUserFromUid上不断得到一个空指针 它返回的“user”对象为null,我不知道为什么。我数据库中的节点称为“用户”(全部小写),我希望通过用户ID检索用户作为模型,并在屏幕上显示名称和电子邮件 有人能看出我错在哪里吗 我的数据库上下文:Java 尝试从Firebase实时数据库检索用户详细信息时使用空指针,java,android,firebase-realtime-database,model-view-controller,nullpointerexception,Java,Android,Firebase Realtime Database,Model View Controller,Nullpointerexception,在我的Android应用程序中,我有一个数据库存储库来联系Firebase实时数据库,还有一个服务层,提供一些方法。我的SaveUserProfile方法可以工作,但我在GetUserFromUid上不断得到一个空指针 它返回的“user”对象为null,我不知道为什么。我数据库中的节点称为“用户”(全部小写),我希望通过用户ID检索用户作为模型,并在屏幕上显示名称和电子邮件 有人能看出我错在哪里吗 我的数据库上下文: public class DbContext implements IDbC
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;
}
我的数据库服务:
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;
}
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];
}
我的用户模型:
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;
}
我要在其中显示用户详细信息的活动:
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;
}
编辑下面的内容
我的回拨:
public interface Callback {
void myResponseCallback(User user);
}
我的编辑背景:
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;
}
公共类DbContext实现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) {
}
});
}
我的编辑数据库服务:
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;
}
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];
}
我编辑的活动:
@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);
}
编辑前调试:
编辑后调试:
从调试中可以看到,在回调接口之前,userDetails为null。在接口实现之后,userDetails不是null,但是所有的对象值都为null。我不知道这是为什么,因为它们都填充在数据库中。有什么想法吗?@a\u local\u谢谢。你能对我的代码更具体一点吗?我真的不知道rstand你的链接,对不起,我是一个初学者。我的例子为你提供了一个完整的教程,告诉你如何自己实现它,如果你在这一过程中遇到困难,欢迎你在这里用你已经尝试过的更新你的问题far@a_local_nobody我想我已经实现了你的解决方案。我已经在上面添加了我的编辑以及调试的一些屏幕截图。如您所见,userDetails对象正在填充,但所有值都为null。这些值在数据库中不是null。有什么想法吗?
返回user1[0];
这也不起作用,因为您收到的值只通过回调模式返回给您,在GetUserFromFirebase
内部,您将是唯一一个引用用户对象的地方,您基本上什么也不返回,这就是它看起来的样子