所以我的后端使用了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) {
}
});
}
目前,该值被添加两次(如果该字段已经存在,则调用两次else;如果不存在则调用它)。我不确定我做错了什么。
答案 0 :(得分: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语句应该是当前的调用,并且仍然按预期禁用监听器。
答案 1 :(得分:1)
听起来相当复杂。在Firebase数据库中,通常最好尽可能地分离读写操作。而push id是按时间顺序存储数据的好方法;如果项目具有自然键,则通常最好将它们存储在该键下。
例如,如果您的String match
确实是String matchId
,则可以使用matchId
作为密钥,确保每次匹配最多一次。
userRef.child("matches").child(matchId).setValue(true);
此操作幂等:无论您多久运行一次,它都会得到相同的结果。
您会注意到我没有检查matches
是否已存在:Firebase数据库会自动创建存储该值所需的所有节点,并自动删除所有没有值的节点。< / p>