我正在使用firebase实时数据库,并且正在将字符串列表存储在特定的存储引用中。当前,要向列表中添加内容
我正在执行以下步骤。
如果dataSnapshot.getValue();
不为null,则(已经存在
db,因此需要在其末尾附加新数据。)
将远程列表从dataSnapshot.getValue();
保存到本地变量。
然后将新数据添加到其末尾
下面是我为此编写的代码
DatabaseReference reference = root()
.child(userId)
.child(list_id);
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
reference.removeEventListener(this);
List<String> value = new ArrayList<>();
if (dataSnapshot.getValue() == null) {
value.add(message);
} else {
if (dataSnapshot.getValue() instanceof List && ((List) dataSnapshot.getValue()).size() > 0 && ((List) dataSnapshot.getValue()).get(0) instanceof String) {
value = (List<String>) dataSnapshot.getValue();
value.add(message);
}
}
reference.setValue(value, (databaseError, databaseReference) -> {
finish();
});
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
finish();
}
private void finish() {
Log.e(TAG,"save finished");
}
});
这是执行简单操作的许多步骤。而且,一直以来,我都是从远程提取整个数据并将新数据附加到它上面。
有没有简单的方法可以做到这一点?我尝试了如下的“ push()”方法
DatabaseReference reference = root()
.child(userId)
.child(list_id).push();
但是它总是向我添加的值添加新的键。任何人都可以解释用更少的代码实现此目标的正确方法是什么?
更新:
我的数据库结构如下所示
答案 0 :(得分:1)
您提供的解决方案非常好,但是为什么要删除回调中的侦听器呢? 我将为您编写代码以使其更简单。请在下面查看:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference listIdRef = rootRef.child("list").child(list_id);
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<String> list = new ArrayList<>();
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String comment = ds.getValue(String.class);
list.add(comment);
}
//Do what you need to do with your list
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage());
}
};
listIdRef.addListenerForSingleValueEvent(valueEventListener);
不要忽略错误。
无需获取实体列表即可在08-10-18
节点中添加新子级的最简单方法是仅使用以下代码行:
Map<String, Object> map = new HashMap<>();
map.put("5", "comment55");
rootRef.child("list").child(list_id).updateChildren(map);
但是,甚至更好的解决方案是使用push()
方法代替列表,地图和子项。因此您的数据库结构应如下所示:
Fireabase-root
|
--- usr100
|
--- 08-10-18
|
--- randomId: "comment1"
|
--- randomId: "comment2"
|
--- randomId: "comment3"
|
--- randomId: "comment4"
代码应如下所示:
String key = rootRef.child("list").child(list_id).push().getKey();
Map<String, Object> map = new HashMap<>();
map.put(key, "comment5");
rootRef.child("list").child(list_id).updateChildren(map);
在这种情况下,您不必担心密钥,它不再是数字。在没有push()
方法帮助的情况下,您需要获取整个列表,如我的答案的第一部分所述,添加新元素并更新数据库中的列表。
答案 1 :(得分:0)
这只是对我已经尝试并正在工作的现有已接受答案的更新。这是相同的过程,只需要较少的代码行,而不使用已接受的答案中提到的ValueEventListener
和updateChildren
方法。
DatabaseReference reference = deviceRootReference().child(userId).child(list_id).push();
Map<String, Object> map = new HashMap<>();
map.put(reference.getKey(), comment);
Tasks.await(reference.updateChildren(map));
注意:此代码同步执行数据库写操作(Tasks.await阻止线程),因此上面的代码段应仅在后台线程中运行