2017-09-23 72 views
0

考虑下面的数据库结构 -儿童与风扇变出

tasks 
    task1 
     title: "My first task" 
     uid: "user1" 
user-tasks 
    user1 
     task1: true 

观察更改为特定用户的任务,你可能会实现这样的事情 -

ref.child("user-tasks").child(uid).observe(.childChanged... 

但问题标题的任何更改都不会反映在用户任务中,因此childChanged事件不会触发。如果你观察到所有的任务,那么对其他用户任务的任何改变都会导致观察者不必要地执行任务。此外,所需的实现将处理其他用户/设备对任务的更新,并且更新会正确触发。

到目前为止,我唯一的想法是用时间戳取代真正的时间戳,并在触发观察者时触发观察者。有没有更好的办法?

+0

'task1:true'代表什么? – 3stud1ant3

+0

是的,我也使用了时间戳方法,并且本地缓存了最后一个同步时间戳(在核心数据中)。后续时间我查询的条目大于上次同步时间戳(来自核心数据)。 – user1046037

+0

@ 3stud1ant3是“查找”表或索引列表,表示用户拥有的每个任务。通过这种方式,该节点包含用户拥有的任务的每个密钥。 – cutiko

回答

0

这取决于你想要完成什么。例如:如果你想显示任务名称列表当前用户,你确实会需要两种类型的听众与您当前的数据模型:

  1. 的侦听器/user-tasks根据用户的任务列表。
  2. 用户名为/tasks下的用户的每个可见任务的侦听器。

这导致1 + N个听众,其中N取决于UI中可见任务的数量。虽然这并不是典型的火力地堡一个技术问题,它需要一些努力,在你的代码正确地管理听众。

另一种方法是复制/user-tasks下的每个任务的名称:

user-tasks 
    user1 
     task1: "My first task" 

有了这些数据的结构,你只需要听/user-tasks获得所有信息显示在任务列表。但是反过来,您现在必须在写操作中处理keeping the duplicated data up to date

没有单一的最佳实践在这里:这一切都取决于需要您的应用程序和你的意愿来复制数据,管理侦听器,并为您的应用程序读取-VS-写入性能要求。

0

在这种情况下,我的确会建议你使用你的任务时间戳,而不是真实的。

然后每次你改变一些东西在你的对象(如标题或别的东西),你将需要更新此值,以及(使用updateChildValues)

这将让你知道,如果(当)的更新发生,它也会调用你的childChanged或childAdded观察者。

你的数据库是这样的,这是完全一样的,你表现出什么,但一个更有意义的值替换真,你的时间戳:

root/ 
|___ tasks/ 
|  |___ taskID1 
|    |___ title : task_title 
|    |___ timestamp : task_timestamp1 
|   ... 
| 
|___ user_tasks/ 
|   |___ userID1 
|      |___ taskID1: task_timestamp1 
|      |___ taskID2: task_timestamp2 
|      ... 
|   ... 

有可能一些其他的解决方案,但这是现在我能想到最简单的方法,这样做并不需要对项目进行很多更改。

0

使用查询。

let taskQuery = taskRef.queryOrdered(byChild: "uid").queryEqual(toValue: "user1") 
taskQuery.observe(.childAdded, with: { snapshot in 
    print(snapshot) 
}) 

这只会在任务添加到user1的任务节点时触发。为.childChanged和.childRemoved添加类似的代码。

而且,存储TASK1:用户节点内真正可能是多余的,因为你可以随时查询user1的任务的任务节点。这取决于你还可能需要哪些数据。