我刚刚开始使用Firebase数据库,我对如何构建数据库感到有些困惑。在以下示例中,我有一个users对象和一个groups对象。每个用户可以是多个组的一部分,每个组可以有多个用户。根据" Structure Your Database"。
,建议的数据库结构如下{
"users": {
"alovelace": {
"name": "Ada Lovelace",
"groups": {
"techpioneers": true,
"womentechmakers": true
}
}
},
"groups": {
"techpioneers": {
"name": "Historical Tech Pioneers",
"startDate": "24-04-1820",
"members": {
"alovelace": true,
"ghopper": true,
"eclarke": true
}
}
}
}
我想说我想在我的应用中显示列表中的所有群组,包括群组名称和开始日期。我该如何进行数据库调用?由于用户对象只包含组的id,我是否必须为每个组单独调用数据库才能找到组的名称和开始日期?如果列表中有许多组,那么这将成为很多调用。我的小组可能还包含很多其他信息,所以这对性能似乎并不好。我可以在一次通话中获取用户的组列表中的所有组吗?
我曾经在用户名下的groups对象中包含名称和开始日期:
"users": {
"alovelace": {
"name": "Ada Lovelace",
"groups": {
"techpioneers":{
"name": "Historical Tech Pioneers",
"startDate": "24-04-1820"
},
"womentechmakers":{
"name": "Women in Technology",
"startDate": "13-10-1823"
}
}
}
}
}
但这个解决方案似乎添加了大量重复数据。此外,如果我想更新名称,我将不得不在多个位置执行此操作。也许我想添加一个赞助商组织对象,它也包含组,然后想要列出它们。然后将有3个地方更新信息。我该如何解决这个问题?
答案 0 :(得分:1)
您将有两种可能性,一种是在每个用户的组节点中存储您需要的数据(复制它)。
另一个,我最推荐的那个,就是在你的第一个观察者中添加observeSingleEvent(of: .value)
(可能是observe(.value)
,observe(.childAdded)
或其他什么) 。
假设您拥有一个包含所有群组成员的数组,以及一个名为AppUser的对象,该对象代表您应用中的用户:
var groupMembers = [AppUser]()
例如,要检测何时将新成员添加到组中,您可以使用.childAdded观察者,例如:
func groupWasAddedObserver(completion: @escaping () -> ()) {
// Add a .childAdded observer to the group's members node (groupId should be defined somewhere) :
groupsRef.child(groupId).child("members").observe(.childAdded, with: { [weak self] (snapshot) in
// When you get the snapshot, store its key, which represents the member id :
let memberId = snapshot.key
// fetch this member's profile information using its id :
self?.getUser(memberId, completion: { (groupMember) in
// Once you got the profile information of this member, add it to an array of all your members for example :
self?.groupMembers.append(groupMember)
// Call the completion handler so that you can update the UI or reload a table view somewhere maybe depending on your needs :
completion()
})
})
}
第二种获取用户数据的方法,知道他或她的身份:
func getUser(_ userId: String, completion: @escaping (AppUser) -> ()) {
// Add the observerSingleEvent observer :
usersRef.child(userId).observeSingleEvent(of: .value, with: { (snapshot) in
// Get the data you need using the snapshot you get :
guard let email = snapshot.childSnapshot(forPath: "email").value as? String else { return }
guard let name = snapshot.childSnapshot(forPath: "name").value as? String else { return }
guard let picUrl = snapshot.childSnapshot(forPath: "picUrl").value as? String else { return }
// Call the completion handler to return your user/member :
completion(AppUser(id: snapshot.key, email: email, name: name, picUrl: picUrl))
})
}
如您所见,您使用快照键获取每个用户的memberId,并使用此memberId获取此特定用户数据。