Java Can';t读取Firebase数据库,数据返回null

Java Can';t读取Firebase数据库,数据返回null,java,android,firebase,firebase-realtime-database,Java,Android,Firebase,Firebase Realtime Database,我正试图从数据库中获取一个特定的用户,但我不能,我还想检查是否已经有一个同名(uid)的节点。我不想获取整个用户列表,然后从中检索一个,因为我认为这对性能不好,我的想法是直接从数据库中获取用户 我尝试了很多方法,但我尝试的所有方法都返回null,我无法从dataSnapshot获取值。我使用一个接口来确保在读取完成后执行代码 currentUser = FirebaseAuth.getInstance().getCurrentUser(); mUserRefere

我正试图从数据库中获取一个特定的用户,但我不能,我还想检查是否已经有一个同名(uid)的节点。我不想获取整个用户列表,然后从中检索一个,因为我认为这对性能不好,我的想法是直接从数据库中获取用户

我尝试了很多方法,但我尝试的所有方法都返回null,我无法从dataSnapshot获取值。我使用一个接口来确保在读取完成后执行代码

        currentUser = FirebaseAuth.getInstance().getCurrentUser();
        mUserReference = FirebaseDatabase.getInstance().getReference("users/"+currentUser.getUid());
        mUserReference.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                user = dataSnapshot.getValue(User.class);

                dataStatus.dataIsLoaded(user);
            }

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

            }
        });
    }
这里是接口

    public interface DataStatus{
        void dataIsLoaded(User user);
    }
当我尝试获取用户时,它会显示NullPointerException

            UserUtils userUtils = new UserUtils();

            userUtils.getUser(new UserUtils.DataStatus() {
                @Override
                public void dataIsLoaded(User user) {
                    mUser = user;
                }
            });
用户创建,当我调用此方法时,我执行
uid=currentUser.getUid()

这里是规则

{
  "rules": {
    "users": {
      "$uid": {
        ".read": "$uid === auth.uid",
        ".write": "$uid === auth.uid"
      }
    }
  }
}

已解决
问题是一段代码,我没有包括在这里,它试图在
dataIsLoaded
接口方法之外访问用户,由于
onDataChange
是异步的,用户尚未下载,因此它与代码冲突。

欢迎来到so社区

请使用
.child()
方法,而不是像下面那样用“/”级联节点 还可以使用
.exists()
方法检查datasnapshot的值是否不为null

currentUser = FirebaseAuth.getInstance().getCurrentUser();
mUserReference = FirebaseDatabase.getInstance().getReference.child("users").child(currentUser.getUid());
mUserReference.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        if(dataSnapshot.exists()) {
            user = dataSnapshot.getValue(User.class);
            dataStatus.dataIsLoaded(user);
        }
    }
    // rest of code
如果你需要进一步的支持,请放心

更新

请将您的侦听器替换为以下内容

currentUser = FirebaseAuth.getInstance().getCurrentUser();
mUserReference = FirebaseDatabase.getInstance().getReference.child("users").child(currentUser.getUid());

Query query = FirebaseDatabase.getInstance().getReference.child("users").orderByKey() 
        .equalTo(currentUser.getUid()); 

query.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        for (DataSnapshot singleSnapshot : dataSnapshot.getChildren()) { // dataSnapshot contains set of returned result of the query
            User user = singleSnapshot.getValue(User.class);
            if (user != null) {
                dataStatus.dataIsLoaded(user);
            }
        }
    }
}

欢迎来到SO社区

您何时调用函数读取用户内容

这可能是一个异步问题

为了确保这一点,请创建一个以用户为参数的函数,并在从DB(onDataChange)读取内容后调用它


另外,当你阅读“用户”时,你有没有试着打印出它里面的内容?如果它为空,那么问题肯定在路径内。如果是这样,请使用.child(“users”).child(currentUser.getUid())

谢谢,我已经尝试过使用
.child
来代替它,但是它不起作用。在添加侦听器之前,您可以记录“currentUser”id并确保它已经在您的数据库节点“users”中吗?我已将其删除以进行检查,并且它位于数据库中,您可以将其与主贴子中的图像进行比较。onDataChange()是否由正确的用户触发。。如果是,则dataStatus.dataIsLoaded(用户);是否正确更新userUtils对象的用户字段?我几乎可以肯定,问题是当我执行
user=dataSnapshot.getValue(user.class)时
user仍然为null,因此
dataStatus.dataIsLoaded(user)
更新null对象。我想它甚至没有输入onDataChange()方法。你能显示用户创建的代码吗?我刚刚添加了它。我的意思是在firebase中创建用户。你能把用户创建的代码放在firebase中吗?是的,对不起,现在可以了。我从地图片段的
OnViewCreated
调用它,我用一个函数对它进行了测试,结果为空
currentUser = FirebaseAuth.getInstance().getCurrentUser();
mUserReference = FirebaseDatabase.getInstance().getReference.child("users").child(currentUser.getUid());

Query query = FirebaseDatabase.getInstance().getReference.child("users").orderByKey() 
        .equalTo(currentUser.getUid()); 

query.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        for (DataSnapshot singleSnapshot : dataSnapshot.getChildren()) { // dataSnapshot contains set of returned result of the query
            User user = singleSnapshot.getValue(User.class);
            if (user != null) {
                dataStatus.dataIsLoaded(user);
            }
        }
    }
}