更新Firebase数据库中的多个路径

问题描述 投票:0回答:2

我的应用程序中有两个实体-UserShift。他们共享多对多关系。

这是我使用非规范化技术和4个顶级节点构造数据库的方式:

{
   "shift-assign":{
      "-Lwo52vuW9QqCmAfS90w":{
         "111":{
            "email":"[email protected]",
            "firstName":"John",
            "id":"111",
            "lastName":"Smith",
            "password":"111",
            "phone":"555",
            "wage":30.0
         },
         "222":{
            "email":"[email protected]",
            "firstName":"Jane",
            "id":"222",
            "lastName":"Doe",
            "password":"222",
            "phone":"678",
            "wage":32.5
         }
      },
      "-Lwsj8yE6HW2IUoTVJ0G":{
         "111":{
            "email":"[email protected]",
            "firstName":"John",
            "id":"111",
            "lastName":"Smith",
            "password":"111",
            "phone":"555",
            "wage":30.0
         }
      }
   },
   "shifts":{
      "-Lwo52vuW9QqCmAfS90w":{
         "date":"20191224",
         "endTime":"12:00",
         "key":"-Lwo52vuW9QqCmAfS90w",
         "startTime":"10:00"
      },
      "-Lwsj8yE6HW2IUoTVJ0G":{
         "date":"20191224",
         "endTime":"14:00",
         "key":"-Lwsj8yE6HW2IUoTVJ0G",
         "startTime":"11:00"
      }
   },
   "user-assign":{
      "111":{
         "-Lwo52vuW9QqCmAfS90w":{
            "date":"20191224",
            "endTime":"12:00",
            "key":"-Lwo52vuW9QqCmAfS90w",
            "startTime":"10:00"
         },
         "-Lwsj8yE6HW2IUoTVJ0G":{
            "date":"20191224",
            "endTime":"14:00",
            "key":"-Lwsj8yE6HW2IUoTVJ0G",
            "startTime":"11:00"
         }
      },
      "222":{
         "-Lwo52vuW9QqCmAfS90w":{
            "date":"20191224",
            "endTime":"12:00",
            "key":"-Lwo52vuW9QqCmAfS90w",
            "startTime":"10:00"
         }
      }
   },
   "users":{
      "99999":{
         "email":"",
         "firstName":"Admin",
         "id":"99999",
         "lastName":"",
         "password":"111",
         "phone":"",
         "wage":0
      },
      "111":{
         "email":"[email protected]",
         "firstName":"John",
         "id":"111",
         "lastName":"Smith",
         "password":"111",
         "phone":"555",
         "wage":30.0
      },
      "222":{
         "email":"[email protected]",
         "firstName":"Jane",
         "id":"222",
         "lastName":"Doe",
         "password":"222",
         "phone":"678",
         "wage":32.5
      }
   }
}

我能够插入,读取和删除UserShift对象,但是在更新它们时,事情变得有些复杂。

例如,如果我想更新用户的工资,则必须遍历该用户分配的所有班次(在user-assign/$id下),存储所有班次的键,然后为每个班次引用shift-assign/$shift-key存储密钥并更新工资。这将需要嵌套的EventListener,我正试图避免。

与显然地更新Shift节点的相同问题。

是否有更好的方法来解决这个问题?

android firebase firebase-realtime-database nosql
2个回答
0
投票

您实际上应该只引用user-assignshift-assign节点中的ID,而不要引用整个对象。非规范化不需要您创建整个文档的重复副本。例如,简化您的结构将导致:

{
   "shift-assign":{
      "-Lwo52vuW9QqCmAfS90w": ["111", "222"],
      "-Lwsj8yE6HW2IUoTVJ0G": ["111"]
   },
   "shifts":{
      "-Lwo52vuW9QqCmAfS90w":{
         "date":"20191224",
         "endTime":"12:00",
         "key":"-Lwo52vuW9QqCmAfS90w",
         "startTime":"10:00"
      },
      "-Lwsj8yE6HW2IUoTVJ0G":{
         "date":"20191224",
         "endTime":"14:00",
         "key":"-Lwsj8yE6HW2IUoTVJ0G",
         "startTime":"11:00"
      }
   },
   "user-assign":{
      "111":["-Lwo52vuW9QqCmAfS90w", "-Lwsj8yE6HW2IUoTVJ0G"],
      "222":["-Lwo52vuW9QqCmAfS90w"]
   },
   "users":{
      "99999":{
         "email":"",
         "firstName":"Admin",
         "id":"99999",
         "lastName":"",
         "password":"111",
         "phone":"",
         "wage":0
      },
      "111":{
         "email":"[email protected]",
         "firstName":"John",
         "id":"111",
         "lastName":"Smith",
         "password":"111",
         "phone":"555",
         "wage":30.0
      },
      "222":{
         "email":"[email protected]",
         "firstName":"Jane",
         "id":"222",
         "lastName":"Doe",
         "password":"222",
         "phone":"678",
         "wage":32.5
      }
   }
}

然后,您可以只执行客户端联接来检索其关联的对象。

这具有几个优点:

  1. 如果要更新用户的数据,则不必在任何节点上更新所有其他出现的用户。同样,如果要更新班次,则只需在一个地方进行更新。
  2. 节省存储空间-同样,您不必创建相同文档的副本。您只需要他们的ID并将其放在一个位置即可。

0
投票

将地图用作路径(重制后)和值,然后使用updateChildren方法

例如,如果要更新用户的多个名称,则为>]

Map<String, Object> map = new HashMap<>();
//key for path and value in map for value in node 
map.put("/users/" + userId1 + "/name/", "ahmad");
map.put("/users/" + userId2 + "/name/", "mahmoud");
map.put("/users/" + userId3 + "/name/", "martin");
map.put("/users/" + userId4 + "/name/", "nameValue");
//and so on
myRootRef.updateChildren(map);

依此类推,如果您有多个数据,则可以使用循环

© www.soinside.com 2019 - 2024. All rights reserved.