如何更新Firebase数据库中的子节点数据?

时间:2018-02-02 05:59:52

标签: java android firebase firebase-realtime-database

实际上我有一个数据库,其中有多个用户。每个用户都有自己的数据,其中还包括一系列对象类型"任务"。我想要做的是更新特定任务的数据。我试过ref.child (userId).child ("Tasks").child ("done").setValue (isDone);,但是在数据库中添加了一个新条目。我的问题是,当我们不知道该节点的UID时,如何更新子节点的数据?我添加了我的数据库的快照,这里用户有UID,并且在其下面有TASKS,其中包含任务的数据,所以我必须更新特定任务的数据,锄头做到这一点??请帮忙。

enter image description here

我尝试了彼得的解决方案,但数据更新如下:

enter image description here

但只有"完成"应该更新。

4 个答案:

答案 0 :(得分:2)

试试这个:

DatabaseReference ref= FirebaseDatabase.getInstance().getReference().child(userId).child("Tasks");

 ref.orderByChild("name").equalTo(nameofthetask).addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.exists()) {
             for (DataSnapshot datas : dataSnapshot.getChildren()) { 
              String key=datas.getKey();
              String name=datas.child("name").getValue().toString();
              String priorities=datas.child("priority").getValue().toString();
              ref.child(key).child("done").setValue(isdone);
              ref.child(key).child("name").setValue(name);
              ref.child(key).child("priority").setValue(priorities);

                }
             } 
          }
            @Override
        public void onCancelled(FirebaseError firebaseError) {

           }

     });

可以执行上述操作,因为用户正在更新任务,那么您可以执行与用户正在更新的任务相同的查询。然后检查它是否存在于用户节点下的数据库中,并更新子done

说明:

首先,在这种情况下,您引用dataSnapshot,它是Tasks:

  DatabaseReference ref= FirebaseDatabase.getInstance().getReference().child(userId).child("Tasks");

现在我们在这里:

       users
          userId
             Tasks <----- here

其次,使用此ref.orderByChild("name").equalTo(nameofthetask)。这就像是说孩子name在哪里等于被称为任务1的任务。

第三,if (dataSnapshot.exists()) {检查数据库中是否存在以上所有内容。

第四,在节点Tasks的直接子节点内循环,这样我就能得到密钥。 String key=datas.getKey();应该是上面示例name的关键:

  users
      userId
         Tasks
            123456 <----------- this will be the key retrieved.
               name: task 1
               done: false
               priority: 5

之后,我还会根据需要检索namepriority,以便在没有namepriority的情况下不会覆盖该节点。

检索上述内容后:

    ref.child(key).child("done").setValue(isdone);
    ref.child(key).child("name").setValue(name);
    ref.child(key).child("priority").setValue(priorities);

我使用上面的代码更新关键节点下的所有3个属性。这不应该创建另一个关键节点,因为它已经存在于数据库中,并且不能有两个相同的键。所以这将会发生:

setValue()之前)

users
  userId
     Tasks
        123456 
           name: task 1
           done: false <------ We need to update done
           priority: 5

(在setValue()之后)

users
   userId
      Tasks
         123456 
            name: task 1
            done: true <------ updated
            priority: 5

答案 1 :(得分:1)

Chandresh Tarasariya的回答是不完整的。彼得的答案应该有效,但也有另一种方法。要更新Firebase数据库中的子项值,您需要具有它的引用。使用其他单词,您需要具有组成引用的所有节点的值。在您的情况下,添加了一个新子项,因为您使用了错误的引用。如您所见,由于您未在代码中使用taskId,因此将孩子添加到错误的位置。

如果您使用以下代码行:

mFirebaseDatabase.child(userId).child("Tasks").child(taskId).child("done").setValue(true);

缺少taskId的值。那么你怎么能解决这个问题呢?

当您将数据添加到数据库并且使用push()方法生成该随机密钥时,将该密钥存储在变量中,如下所示:

String taskKey = mFirebaseDatabase.child(userId).child("Tasks").push().getKey();

因此,拥有此密钥,您现在可以在您的参考中使用它,如下所示:

mFirebaseDatabase.child(userId).child("Tasks").child(taskKey).child("done").setValue(true);

答案 2 :(得分:0)

您也可以使用以下代码更新Firebase。如果您已使用HashMap创建询问数据

fuser.getUid可以是mailId-用于验证Firebase

reference = FirebaseDatabase.getInstance().getReference("Tasks").child(fuser.getUid());
                HashMap<String, Object> map = new HashMap<>();
                map.put("name", ""+"XXXX");
                map.put("priority", ""+"6");
                reference.updateChildren(map);

也可以对所有其他值执行此操作。

答案 3 :(得分:-1)

 mFirebaseDatabase.child(userId).child("Tasks").child(taskId).child("done").setValue(true);