Android 从Firebase检索数据返回null

Android 从Firebase检索数据返回null,android,firebase,firebase-realtime-database,Android,Firebase,Firebase Realtime Database,我在Firebase的数据库中存储了一个用户。当我想要检索用户时,它是空的,我无法解释为什么。我的用户类只是由字符串“email”和字符串“name”和布尔值“firstAppUse”组成 因此,我编写了以下方法从数据库检索用户: public static User getUser(){ final User [] user = new User[1]; DatabaseHelper.userDB.addValueEventListener(new ValueEventLis

我在Firebase的数据库中存储了一个用户。当我想要检索用户时,它是空的,我无法解释为什么。我的用户类只是由
字符串
“email”和
字符串
“name”和
布尔值
“firstAppUse”组成

因此,我编写了以下方法从数据库检索用户:

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];
}
缩小所有期望值
用户[0]
为空。虽然元素存在于数据库中,并且在
DatabaseHelper.userDB
中对它的引用很好:

public class DatabaseHelper {
private static FirebaseDatabase database = FirebaseDatabase.getInstance();
public static DatabaseReference userDB = database.getReference("users/" + FirebaseAuth.getInstance().getCurrentUser().getUid());
}
有人看到这个问题吗?提前感谢。

Firebase数据库是异步的

当代码进入“return”行时,“onDataChange”回调中的代码块没有执行


用户[0]将始终为空,因为firebase数据库是异步的

// 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) {

        }
    });
}

从firebase获取数据时,这是一个异步任务。如果调用getUser()并返回user[0],则它将始终返回null,因为在从firebase获取结果(
DataSnapshot
)之前,您已返回函数

这是密码

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);
        }
    });

}
以下是您应该如何调用此函数:

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;
        }
    });

这将使您的代码模块化。您可以在代码中的任何位置调用此函数以获取用户对象,并且您可以将所有firebase数据库侦听器代码保存在一个位置,以分离数据库层和逻辑层。

是否可以尝试在其中创建日志,以查看dataSnapshot.exists()是否返回true?用户[0]将始终为空,因为firebase数据库为空async@Salman500你能再解释一下吗?当你异步执行某个任务时,你可以在它完成之前转移到另一个任务。这个答案是完全错误的。因为ValueEventListener回调已在主线程中。不需要创建处理程序、消息等@YayoArellano-true。如果你想使用连续侦听器,那么它应该在主线程上,但对于单次查询,我相信我们可以使用此方法分离调用。@YayoArellano如果你能提供一种更好的方法,将我的单值查询与活动代码分离,那将是一个很大的帮助。更简单的方法是创建一个接口,不需要使用用户处理程序。看看这个要点,我刚才在飞行中做的,它可能有错误,但重要的是你得到的想法。