加载"相关"的最佳方法是什么? swift中的数据?
常见设置,如果我有一个用户列表全部存储在follows
节点下,并且包含存储uid的"users" : {
"abc123" : {
"email" : "test@test.com",
"follows" : {
"xyz789" : true
}
},
"xyz789" : { ... }
}
列表,例如:
uid
为一个用户遵循的所有用户加载数据的最有效方法是什么?是否最好使用observeSingleEvent(of: .value)
遍历每个func loadRelated(user: User, completion: @escaping (Bool, [UserObject]) -> ()) {
let ref = Database.database().reference(withPath: "users/" + user.uid + "/follows")
ref.observeSingleEvent(of: .value) { snapshot in
var uids = [String]()
for child in snapshot.children {
let userData = child as! DataSnapshot
uids.append(userData.key)
}
let userRef = Database.database().reference(withPath: "users")
var users = [UserObject]()
var count = 0
uids.forEach { uid in
userRef.child(uid).observeSingleEvent(of: .value) { snapshot in
let user: UserObject(from: snapshot)
users.append(user)
count += 1
if count == uids.count {
completion(true, users)
}
}
}
}
}
?
这是我提出的解决方案,但感觉有些麻烦:
<div class="form-group">
<label class="control-label col-md-3">Posisi ID</label>
<div class="col-md-9">
<textarea name="description" id="description" rows="10" cols="80"></textarea>
<input type="hidden" name="posting_date" id="posting_date">
<input type="hidden" name="id" id="id">
</div>
</div>
我真的不想走非规范化路径并将每个用户数据存储在顶级用户之下。
答案 0 :(得分:1)
如果您决定使用实时数据库,最佳做法是在您的案例中创建另一个名为user-follows
的根节点。您可以通过将值设置为user-follows/$uid/$fid
在路径true
处创建关注,然后在您的应用上,您必须observeSingleEvent
为每个快照键($fid
)设置{ {1}}。
为避免必须单独观察每个关注,而不是将值设置为user-follows/$uid
,您只需在true
中存储有关用户所需的数据。但是,用户可能会更改其用户名,因此您需要将每个user-follows/$uid
内的数据保持最新状态。当用户更改信息时,您可以使用Firebase云功能维护user-follows
。
否则,我建议查看Firebase Firestore,其中允许嵌套。
答案 1 :(得分:1)
如果您知道 / users 中的节点始终包含的用户很少,您可以尝试通过路径 / users <observeSingleEvent(of:)
一次性获取所有用户/ em>的。然后使用 ../ follow 中的用户过滤用户。
这可能会提取更多数据,但可能更快(不确定)并且需要更少的代码来处理。
事实上,您的初始实现已经非常高效。只需确保正确处理observeSingleEvent(of:)
失败,否则条件count == uids.count
永远无法完成。
顺便在 ../下面存储每个用户将只复制您的数据并且难以维护更新。所以是的,避免它。