实施具有多对多关系的Android + Web(Angular)+ Firebase应用:用户< - >窗口小部件(窗口小部件可以与多个用户共享)。
考虑:
实现抓取(join-style)的方法之一是通过多个侦听器来使用此建议:https://www.firebase.com/docs/android/guide/structuring-data.html(“Joining Flattened Data
”)。
但是我对这种方法有疑问,因为我发现数据加载会慢得令人担忧(至少在Android上) - 我在另一个问题中询问了这个问题 - Firebase Android: slow "join" using many listeners, seems to contradict documentation。
所以,这个问题是关于另一种方法:用户拥有的所有小部件的每用户副本。正如Firebase + Udacity教程“ShoppingList ++”(https://www.firebase.com/blog/2015-12-07-udacity-course-firebase-essentials.html)中所使用的那样。
他们的结构如下:
特别是这部分 - userLists
:
"userLists" : {
"abc@gmail,com" : {
"-KBt0MDWbvXFwNvZJXTj" : {
"listName" : "Test List 1 Rename 2",
"owner" : "xyz@gmail,com",
"timestampCreated" : {
"timestamp" : 1456950573084
},
"timestampLastChanged" : {
"timestamp" : 1457044229747
},
"timestampLastChangedReverse" : {
"timestamp" : -1457044229747
}
}
},
"xyz@gmail,com" : {
"-KBt0MDWbvXFwNvZJXTj" : {
"listName" : "Test List 1 Rename 2",
"owner" : "xyz@gmail,com",
"timestampCreated" : {
"timestamp" : 1456950573084
},
"timestampLastChanged" : {
"timestamp" : 1457044229747
},
"timestampLastChangedReverse" : {
"timestamp" : -1457044229747
}
},
"-KByb0imU7hFzWTK4eoM" : {
"listName" : "List2",
"owner" : "xyz@gmail,com",
"timestampCreated" : {
"timestamp" : 1457044332539
},
"timestampLastChanged" : {
"timestamp" : 1457044332539
},
"timestampLastChangedReverse" : {
"timestamp" : -1457044332539
}
}
}
},
如您所见,购物清单"Test List 1 Rename 2"
信息的副本出现在两个地方(2位用户)。
以下是完整性的其余部分:
{
"ownerMappings" : {
"-KBt0MDWbvXFwNvZJXTj" : "xyz@gmail,com",
"-KByb0imU7hFzWTK4eoM" : "xyz@gmail,com"
},
"sharedWith" : {
"-KBt0MDWbvXFwNvZJXTj" : {
"abc@gmail,com" : {
"email" : "abc@gmail,com",
"hasLoggedInWithPassword" : false,
"name" : "Agenda TEST",
"timestampJoined" : {
"timestamp" : 1456950523145
}
}
}
},
"shoppingListItems" : {
"-KBt0MDWbvXFwNvZJXTj" : {
"-KBt0heZh-YDWIZNV7xs" : {
"bought" : false,
"itemName" : "item",
"owner" : "xyz@gmail,com"
}
}
},
"uidMappings" : {
"google:112894577549422030859" : "abc@gmail,com",
"google:117151367009479509658" : "xyz@gmail,com"
},
"userFriends" : {
"xyz@gmail,com" : {
"abc@gmail,com" : {
"email" : "abc@gmail,com",
"hasLoggedInWithPassword" : false,
"name" : "Agenda TEST",
"timestampJoined" : {
"timestamp" : 1456950523145
}
}
}
},
"users" : {
"abc@gmail,com" : {
"email" : "abc@gmail,com",
"hasLoggedInWithPassword" : false,
"name" : "Agenda TEST",
"timestampJoined" : {
"timestamp" : 1456950523145
}
},
"xyz@gmail,com" : {
"email" : "xyz@gmail,com",
"hasLoggedInWithPassword" : false,
"name" : "Karol Depka",
"timestampJoined" : {
"timestamp" : 1456952940258
}
}
}
}
然而,在我开始在我的应用程序中实现类似的结构之前,我想澄清一些疑问。
以下是我相互关联的问题:
ownerMappings
节点中分配一个“所有者”。因此,没有人可以重命名购物清单。我想拥有多个“所有者”/管理员,拥有平等的权利。这样的每个用户的保留副本结构是否仍适用于多个所有者/管理员用户,而不会有数据损坏/“失步”或“恶作剧”的风险? PS:我知道通过updateChildren()
进行原子多路径更新 - 肯定会使用它们。
欢迎任何其他提示/观察。 TIA。
答案 0 :(得分:0)
我建议只为整个系统提供一个小部件的副本。它将具有原始用户ID和一组有权访问它的用户。窗口小部件树可以保存用户权限并更改历史记录。每次进行更改时,都会在树中添加一个分支。然后可以促销分支机构#34;到#"主人"有点像GIT。这将保证数据完整性,因为以前的版本永远不会被更改或删除。它也会简化你的提取......我认为:)
{
users:[
bob:{
widgets:[
xxx:{
widgetKey: xyz,
permissions: *,
lastEdit...
}
]
}
...
]
widgets:[
xyz:{
masterKey:abc,
data: {...},
owner: bob,
},
...
]
widgetHistory:[
xyz:[
v1:{
data:{...},
},
v2,
v3
]
123:[
...
],
...
]
}