2017-08-04 72 views
1

我正在编写事件列表应用程序,它具有事件>零件>步骤的层次结构。创建活动后,我可以“进入”活动并查看包含“步骤”列表的“部分”列表。Firebase数据库更新正在删除子数据

我构建数据库的方式是让我有一个按用户ID排序的对象以显示事件及其详细信息,然后如果我单击该事件,我会进入它,现在查看parts对象。部件对象看起来像这样:

parts: 
    eventID1: 
     partID1: 
      startDateTime:value, 
      endDateTime:value, 
      title:value, 
      ... 
     partID2: 
      startDateTime:value, 
      endDateTime:value, 
      title:value, 
      ... 
     etc. 

这很好,我拉每个事件ID的所有部分。问题出现在步骤中。当我为零件添加一个步骤时,我将它放在两个位置(使用update);一个在一个步骤表,一个在部件本身,添加新键:值的part

步骤对象看起来是这样的:

steps: 
    eventID1: 
     partID1: 
      stepID1: 
       title:value, 
       startDateTime:value, 
       etc. 
      stepID2: 
       title:value, 
       startDateTime:value, 
       etc. 

最后(问题区域)的部分对象更新到这个样子:

parts: 
    eventID1: 
     partID1: 
      startDateTime:value, 
      endDateTime:value, 
      title:value, 
      ... 
      steps: 
       stepID1: 
        title:value, 
        startDateTime:value, 
        etc. 
       stepID2: 
        title:value, 
        startDateTime:value, 
        etc. 
     partID2: 
      startDateTime:value, 
      endDateTime:value, 
      title:value, 
      ... 
     etc. 

我添加上述(再次使用update)部分中的步骤。现在的问题是,当我编辑零件的标题或日期时,它会返回更新但内部没有任何步骤。它会擦除这些步骤。

每个eventpartstep具有相同的结构,所以我结合所有这些成一个单一的函数(使用离子3/angular4)

update(action, type, eid, pid, sid, title, location, startDateTime) { 
    console.log("Firebase Database Receiving: ", action, type, eid, pid, sid, title, location, startDateTime); 
    let key = (action === "add") ? this.ref.push().key : null; 
    console.log(key); 
    let update; 
    let object = { 
     startDateTime: startDateTime, 
     startDateTimeEpoch: moment(startDateTime).format("X"), 
     endDateTime: startDateTime, 
     endDateTimeEpoch: moment(startDateTime).format("X"), 
     title: title, 
     type: type, 
     roles: { 
     [this.firebaseAuthentication.uid]: "admin", 
     }, 
     location: { 
     title: location, 
     street: '', 
     city: '', 
     state: '', 
     zip: '', 
     timeZone: '' 
     }, 
    }; 
    if(type === "events"){ 
     key = (key) ? key : eid; 
     if(action !== "delete") { 
     update = { 
      ['events/' + key]: object, 
      ['roles/' + this.firebaseAuthentication.uid + '/' + key]: object 
     } 
     } else { 
     console.log("delete event", key); 
     update = { 
      ['events/' + key]: null, 
      ['roles/' + this.firebaseAuthentication.uid + '/' + key]: null, 
      ['parts/' + key]: null, 
      ['steps/' + key]:null 
     } 
     } 
    } else if(type === "parts") { 
     key = (key) ? key : pid; 
     if(action !== "delete") { 
     update = { 
/************ . Here is the update object . ***********/ 
      ['parts/' + eid + '/' + key]: object 
     } 
     } else { 
     update = { 
      ['parts/' + eid + '/' + key]: null, 
      ['steps/' + eid + '/' + key]: null 
     } 
     } 
    } else if(type === "steps") { 
     key = (key) ? key : sid; 
     if(action !== "delete") { 
     update = { 
      ['parts/' + eid + '/' + pid + '/steps/' + key]: object, 
      ['steps/' + eid + '/' + pid + '/' + key]: object 
     } 
     } else { 
     update = { 
      ['parts/' + eid + '/' + pid + '/steps/' + key]: null, 
      ['steps/' + eid + '/' + pid + '/' + key]: null 
     } 
     } 
    } 
    console.log(object, update); 
    return new Promise((resolve, reject) => { 
/**************** . Finally the actual update function ************/ 
     this.ref.update(update).then(success => { 
     resolve(success); 
     }, error => { 
     reject(error); 
     }); 
    }); 
    } 

这基本上遍历,具体action/type组合是edit/part

从我读到的有关firebase的update()的信息来看,它不应该破坏对象内任何未触及的数据。这应该像set(),但我不明显。

有什么想法?坦率?

+0

你已经粘贴了一大堆代码,而最少的代码将会更有帮助。要记住的最大的事情是,你必须在斜线分隔的路径中放置所有的特异性*。更新将覆盖关键级别的所有内容,因此除非您想覆盖整个内容,否则不能执行任何嵌套对象。 –

+0

@MichaelBleigh,是的,我粘贴了很多代码,但都是相关的(除了另外两个更新语句)。至于更新,如果我要在该对象中放置一个空白的'steps'项目,它会不会覆盖那里的内容? (这不是一个很好的例子,因为步骤会在这一切的任何事情,但只是检查点) – ntgCleaner

+1

我的观点是,如果我做'更新({'富/酒吧':{巴兹:'qux',一些:'东西' })'foo/bar'下的所有内容都被覆盖。相反,我应该做'update({'foo/bar/baz':'qux','foo/bar/some':'thing'})'。我不确定这是否是问题,因为有太多的代码需要排序,我没有时间:) –

回答

1

从我从代码中收集的更新函数按照我的预期工作(来自经验而非文档)。我的意思是说,通过将某个键设置为一个对象来进行更新的确如此,它将键值设置为您传递的对象。一个例子:

用户:

  • NIK

    • 年龄:18
    • ID:1
  • 乔治

    • 年龄:29
    • ID:2

令obj = {年龄:24};

调用更新({nik:obj})实际上将nik设置为您提供的对象的值(因此删除了id)。有理由对吗?那么火力确实说的更新:

如果您想写信给在同一时间一个数据库位置的多个孩子,而不会覆盖其他子节点,您可以使用更新方法如下所示:

可能不清楚的是,它意味着其他子级节点与您正在更新的密钥处于同一级别(即乔治)。

+0

我的实验显示相同。以及Michael上面的讽刺评论。你说得对,这听起来有点奇怪,但指出它是有道理的。对于firebase,子节点是更高层次的项目,而不是您正在编辑的对象的子项。现在可以理解了 – ntgCleaner