android - 将数据添加到 Firebase 实时数据库中的列表的最佳方法是什么
问题描述
我正在使用 firebase 实时数据库,并将字符串列表存储在特定的存储引用中。目前,要向列表中添加一些内容
我正在执行以下步骤。
- 读取数据库子引用
- 获取数据快照并检查它是否为空(这意味着第一次)
- 如果为null,直接设置你的本地列表
如果
dataSnapshot.getValue();
不为空,则(数据库中已经存在数据,因此需要将新数据附加到它的末尾。)将远程列表保存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();
但它总是为我添加的值添加一个新键。谁能用更少的代码解释什么是正确的方法?
更新:
我的数据库结构如下所示
解决方案
您提供的解决方案非常好,但是为什么要删除回调中的侦听器呢?我会为您编写更简单的代码。请看下面:
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()
方法的帮助,您需要获取整个列表,如我的答案的第一部分所述,添加新元素并更新数据库中的列表。
推荐阅读
- javascript - 更改代码组织时的 JQuery Select
- .net - .NET TreeView 更改扩展符号(+/- 到 > 符号)
- google-app-engine - 使用 gcloud 设置目标网址
- arrays - 根据下拉列表在列中查找值的公式
- javascript - 如何在数组对象中创建嵌套树
- r - 如何根据频率更改列中的每个值,除了某些值
- sql - 从 SQL 登录验证中查询密码
- python - 如何使用 JPEG 压缩保存 uint16 NumPy 数组,并加载 uint16 JPEG 压缩数据?
- python - Python - 将列表中的数字乘以位置(0、1、2、3等)而不是值(2、4、6、8等)
- drools - OptaPlanner ECJ 依赖项。替换或预编译 drools 以进行本地安装