简体   繁体   English

无法读取 Firebase 数据库,数据返回 null

[英]Can't read Firebase database, data returns null

I'm trying to get a specific user from the database but I can't, also I would like to check if there is already a node with the same name (uid).我正在尝试从数据库中获取特定用户,但我不能,我还想检查是否已经有一个具有相同名称(uid)的节点。 I don't want to get the whole list of users and then retrieve one from it because I don't think that's good for perfomance, my idea is to directly get the user from the database我不想获取整个用户列表然后从中检索一个,因为我认为这对性能没有好处,我的想法是直接从数据库中获取用户

I tried many ways but everything I try returns null, I can't get the values from dataSnapshot.我尝试了很多方法,但我尝试的所有方法都返回 null,我无法从 dataSnapshot 中获取值。 I use an interface to make sure I execute the code after the reading is done我使用接口来确保在读取完成后执行代码

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

            }
        });
    }

Here the interface界面在这里

    public interface DataStatus{
        void dataIsLoaded(User user);
    }

And when I try to get the user it shows NullPointerException当我尝试获取用户时,它显示 NullPointerException

            UserUtils userUtils = new UserUtils();

            userUtils.getUser(new UserUtils.DataStatus() {
                @Override
                public void dataIsLoaded(User user) {
                    mUser = user;
                }
            });

User creation, when I call this method I do uid = currentUser.getUid()用户创建,当我调用此方法时,我会执行uid = currentUser.getUid()

    public void createNewUser(String uid, String name, String email, DataStatus dataStatus) {
        mUserReference = mDatabase.child("users").child(uid);
        mUserReference.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                user = new User(name, email);
                mDatabase.child("users").child(uid).setValue(user);
                dataStatus.dataIsLoaded(user);
            }

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

            }
        });
    }

Here the rules这里的规则

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

Here's how my data base is organized这是我的数据库的组织方式

SOLVED The problem was a piece of code, which I didn't include here, that was trying to get access to the user outside the dataIsLoaded interface method, and as onDataChange is asynchronous the user hadn't been downloaded yet so it was conflicting with the code.解决问题是一段代码,我没有在这里包含,它试图在dataIsLoaded接口方法之外访问用户,并且由于onDataChange是异步的,因此用户尚未下载所以它与编码。

Welcome to SO community欢迎来到 SO 社区

Please use .child() method instead of cascading nodes with "/" as below Also check if the value of the datasnapshot is not null using .exists() method请使用.child()方法代替带有“/”的级联节点,如下所示另外使用.exists()方法检查数据快照的值是否不是 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

Feel free if you need further support如果您需要进一步的支持,请随意

UPDATE更新

Please replace your listener with below请用以下替换您的听众

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

Welcome to SO community.欢迎来到 SO 社区。

When did you call your function to read the user content?你什么时候打电话给你的 function 来读取用户内容的?

it might be an asynchronous problem.这可能是一个异步问题。

To make sure, make a function where the user is the parameter and call it once you read something from the DB (onDataChange).为了确保,在用户是参数的地方创建一个 function 并在从数据库中读取某些内容后调用它(onDataChange)。

Plus, did you try to print out what is inside " user " when you read it?另外,当您阅读它时,您是否尝试打印出“用户”内部的内容? if it gives you null, the problem is within the path for sure.如果它给你 null,那么问题肯定在路径之内。 If so, use.child("users").child(currentUser.getUid())如果是这样, use.child("users").child(currentUser.getUid())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM