【问题标题】:Can't read Firebase database, data returns null无法读取 Firebase 数据库,数据返回 null
【发布时间】:2019-10-02 00:13:01
【问题描述】:

我正在尝试从数据库中获取特定用户,但我不能,我还想检查是否已经有一个具有相同名称(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()

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

            }
        });
    }

这里是规则

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

Here's how my data base is organized

已解决 问题是一段代码,我没有在这里包含它,它试图在dataIsLoaded 接口方法之外访问用户,并且由于onDataChange 是异步的,用户还没有被下载所以它与代码冲突。

【问题讨论】:

  • 你能显示创建用户的代码吗
  • 是的,我刚刚添加了它
  • 我的意思是在 firebase 中创建用户。
  • 你能把创建用户的代码放到firebase里吗?
  • 是的,抱歉,已经完成了

标签: java android firebase firebase-realtime-database


【解决方案1】:

欢迎来到 SO 社区

请使用.child()方法而不是使用“/”级联节点如下 同时使用.exists()方法检查datasnapshot的值是否不为空

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

【讨论】:

  • 谢谢,我已经尝试过使用.child,但它也不起作用
  • 您能否在添加监听器之前记录“currentUser” id 并确保它已经在您的数据库节点“users”中?
  • 我调试了一下,在数据库里,你可以和主帖里的图片对比currentUser uid
  • onDataChange() 是否由正确的用户触发? .. 如果是的话 dataStatus.dataIsLoaded(user);正确更新 userUtils 对象的用户字段?
  • 我几乎可以肯定它是,问题是当我做user = dataSnapshot.getValue(User.class); 用户仍然为空所以dataStatus.dataIsLoaded(user) 更新一个空对象。我认为它甚至没有进入 onDataChange() 方法
【解决方案2】:

欢迎来到 SO 社区。

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

这可能是一个异步问题。

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

另外,当您阅读“用户”时,您是否尝试将其打印出来?如果它给你null,那么问题肯定在路径之内。如果是这样,请使用 .child("users").child(currentUser.getUid())

【讨论】:

  • 我从地图片段的OnViewCreated 调用它,我用一个函数对其进行了测试,结果为空
猜你喜欢
  • 2019-12-04
  • 1970-01-01
  • 1970-01-01
  • 2020-08-20
  • 1970-01-01
  • 2019-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多