首页 文章

firebase检查孩子是否存在

提问于
浏览
0

所以我的后端使用了firebase . 我的目标是将用户匹配添加到用户ID . 但是,当用户最初注册时,他们没有匹配 . 我要做的是检查用户子节点中是否存在“匹配”子节点,如果没有创建列表子节点并存储第一个匹配项 . 但是,如果它已经存在,则只需添加匹配 . 这是我的代码:

public void setMatch(final String match){
    final Firebase ref = new Firebase("FIREBASEURL");
    final Firebase userRef = ref.child("Flights").child(userName);
    userRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            System.out.println("does the child exist? " + dataSnapshot.child("matches").exists());
            if(!dataSnapshot.child("matches").exists()){
                ArrayList<String> matches = new ArrayList<String>();
                matches.add(match);
                Firebase matchesRef = userRef.child("matches");
                matchesRef.setValue(matches);
                userRef.removeEventListener(this);
            }else if(dataSnapshot.child("matches").exists()){
                Map<String, Object> matches = new HashMap<>();
                matches.put("matches", match);
                userRef.child("matches").push().setValue(matches);
                userRef.removeEventListener(this);
            }
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {

        }
    });
}

目前,该值被添加两次(如果该字段已经存在则调用两次,否则调用它;如果不存在则调用它) . 我不确定我做错了什么 .

2 回答

  • 1

    这听起来相当复杂 . 在Firebase数据库中,通常最好尽可能地分离读写操作 . 而push id是按时间顺序存储数据的好方法;如果项目具有自然键,则通常最好将它们存储在该键下 .

    例如,如果您的 String match 确实是 String matchId ,则可以使用 matchId 作为密钥,确保每次匹配最多一次 .

    userRef.child("matches").child(matchId).setValue(true);
    

    此操作是幂等的:无论您多久运行一次,它都会产生相同的结果 .

    matches 的检查已经存在:Firebase数据库会自动创建存储该值所需的所有节点,并自动删除所有没有值的节点 .

  • 1

    看起来你创建了if块中不存在的字段,然后测试该字段(刚创建的字段)是否存在,现在它确实存在,所以它再次添加它 . removeEventListener调用将删除侦听器,但不会阻止当前代码完成 .

    尝试:

    if(!dataSnapshot.child("matches").exists()){
                ArrayList<String> matches = new ArrayList<String>();
                matches.add(match);
                Firebase matchesRef = userRef.child("matches");
                matchesRef.setValue(matches);
                userRef.removeEventListener(this);
                return; 
            }else if(dataSnapshot.child("matches").exists()){
                Map<String, Object> matches = new HashMap<>();
                matches.put("matches", match);
                userRef.child("matches").push().setValue(matches);
                userRef.removeEventListener(this);
            }
    

    添加return语句应该是当前调用,并且仍然按预期禁用监听器 .

相关问题