如何使用Firebase和Swift快速获得关注者并跟踪计数

时间:2017-10-23 17:13:52

标签: swift firebase

我目前正在尝试使用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)
    }

}

问题是这需要很长时间才能加载,并且当您查看用户的个人资料时,通常会冻结整个应用。如何加快速度或提高工作效率?

1 个答案:

答案 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