将数据添加到Firebase Realtime数据库中的列表的最佳方法是什么

问题描述:

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

I'm using firebase realtime db, and I'm storing a list of string in a particular storage reference. Currently, to add something to the list

我正在执行以下步骤.

I'm doing the following steps.

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

  1. Read the database childreference
  2. get the datasnapshot and check if it is null (which means first time)
  3. if it is null, directly set your local list
  4. if dataSnapshot.getValue(); not null then (already data present in the db, so need to append the new data to th e end of it.) save the remote list from dataSnapshot.getValue(); to a local variable.

然后将新数据添加到其末尾

then add the new data to the end of it

下面是我为此编写的代码

Below is the code I have written for that

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");
    }
});

这是执行简单操作的许多步骤.而且,一直以来,我一直在从远程提取整个数据并将新数据附加到其中.

Thats a lot of steps to do a simple operation. Also , all the time I'm pulling the whole data from remote and appending the new data to it.

有没有简单的方法可以做到这一点?我尝试了如下的"push()"方法

is there any easy way to do this? I tried with the 'push()' method as follows

DatabaseReference reference = root()
    .child(userId)
    .child(list_id).push();

但是它总是向我添加的值添加新的键.任何人都可以解释用更少的代码实现此目标的正确方法是什么?

But it adds a new key always to the value I add. Can anyone explain what is the proper way to do it with less code?

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

UPDATE:
My db structure is as shown below

您提供的解决方案很好,但是为什么要删除回调中的侦听器呢? 我将为您编写代码以使其更简单.请在下面查看:

The solution you gave it's very good but why to remove the listener inside the callback? I'll write you the code to be more simpler. Please see it below:

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

不要忽略错误.

无需获取enitire列表即可在08-10-18节点中添加新子级的最简单方法是仅使用以下代码行:

The simplest way in which you can add a new child in your 08-10-18 node, without the need to get the enitire list, would be using only the following lines of code:

Map<String, Object> map = new HashMap<>();
map.put("5", "comment55");
rootRef.child("list").child(list_id).updateChildren(map);

但是,甚至更好的解决方案是使用push()方法代替列表,地图和子项.因此,您的数据库结构应如下所示:

But even a better solution would be to use instead of lists, maps and the children should be added using the push() method. So your database structure should look like this:

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

In this case you don't have to worry about the key, which is not a number anymore. Without the help of the push() method, you need to get the entire list, as explained in the first part of my answer, add the new element and the update the list in the database.