我目前正在尝试使用firebase获取特定用户的所有关注者。在我的didSet子句中,我调用函数setFollowingCount()来获取当前用户所遵循的用户并将其分配给文本字段:
var user: User? {
didSet {
setFollowingCount()
guard let following = self.user?.following else {return}
let attributedText = NSMutableAttributedString(string: "\(following)\n", attributes: [NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: 14)])
attributedText.append(NSAttributedString(string: "followers", attributes: [NSAttributedStringKey.foregroundColor: UIColor.lightGray, NSAttributedStringKey.font: UIFont.systemFont(ofSize: 14)]))
self.followingLabel.attributedText = attributedText
}
}
setFollowingCount()函数是:
func setFollowingCount(){
var i = 0
guard let userId = self.user?.uid else { return }
Database.database().reference().child("following").child(userId).observe(.value) { (snapshot) in
self.user?.following = Int(snapshot.childrenCount)
}
}
问题是这需要很长时间才能加载,并且当您查看用户的个人资料时,通常会冻结整个应用。如何加快速度或提高工作效率?
答案 0 :(得分:2)
self.user?.following = Int(snapshot.childrenCount)
不是一种有效的解决方案。 .childrenCount
实际上遍历快照并计算所有将要缓慢的子项。
相反,您希望将关注者数量存储为单个值,以便更快地检索它。
following: {
uid: {
followingCount: 100,
follwersCount: 150
}
}
然后你可以像这样查询:
Database.database().reference().child("following").child(userId).observeSingleEvent(of: .value) { (snapshot) in
if let counts = snap.value as? [String: AnyObject] }
let followingCount = counts["followingCount"] as? Int
let followersCount = counts["followersCount"] as? Int
// save these values somewhere
}
})
我还建议您在事务块中递增/递减跟随者计数,这样计数就不会搞砸了。这看起来像这样:
static func incrementCount(countName: String) {
if let uid = Auth.auth().currentUser?.uid {
let databaseReference = Database.database().reference()
databaseReference.child("following").child(uid).runTransactionBlock { (currentData: MutableData) -> TransactionResult in
if var data = currentData.value as? [String: Any] {
var count = data[countName] as! Int
count += 1
data[countName] = count
currentData.value = data
return TransactionResult.success(withValue: currentData)
}
return TransactionResult.success(withValue: currentData)
}
}
}
最后,
如果您要使用.observe
,则需要删除引用。在这种情况下,虽然您不是在寻找更新,但您可以使用.observeSingleEvent