首页 > 解决方案 > 将数据添加到 Firebase 实时数据库中的列表的最佳方法是什么

问题描述

我正在使用 firebase 实时数据库,并将字符串列表存储在特定的存储引用中。目前,要向列表中添加一些内容

我正在执行以下步骤。

  1. 读取数据库子引用
  2. 获取数据快照并检查它是否为空(这意味着第一次)
  3. 如果为null,直接设置你的本地列表
  4. 如果dataSnapshot.getValue();不为空,则(数据库中已经存在数据,因此需要将新数据附加到它的末尾。)将远程列表保存 dataSnapshot.getValue();到本地变量。

    然后将新数据添加到它的末尾

  5. 现在本地列表包含远程中的所有项目以及新项目。将此保存到子参考

下面是我为此编写的代码

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

但它总是为我添加的值添加一个新键。谁能用更少的代码解释什么是正确的方法?

更新:
我的数据库结构如下所示

在此处输入图像描述

标签: androidfirebasefirebase-realtime-database

解决方案


您提供的解决方案非常好,但是为什么要删除回调中的侦听器呢?我会为您编写更简单的代码。请看下面:

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()方法的帮助,您需要获取整个列表,如我的答案的第一部分所述,添加新元素并更新数据库中的列表。


推荐阅读