首页 > 解决方案 > FirebaseDatabase runTransaction 块问题

问题描述

我正在努力FirebaseDatabase更新runTransactionBlock. 这个块应该增加likesCountrecordsCount。最初,当发布帖子时,这些设置为 0。因此,我正在检查是否likesCount == 0,如果是,则这意味着这是帖子的第一个类似,因此它只需likes使用 userUid 和值设置数组true在单独的节点中。然后在这个节点中增加likesCountand并更新它们的值。第一次,这行得通。它设置了它们的值。recordsCountrunTransactionBlock

func incrementLikes(postId: String, onSuccess: @escaping (Post) -> Void, onError: @escaping (_ errorMessage: String?) -> Void) {

    let postRef = Api.Post.REF_POSTS.child(postId)

    postRef.runTransactionBlock({ (currentData) -> TransactionResult in
        if var post = currentData.value as? [String : AnyObject] {

            var likesCount = post["likesCount"] as? Int ?? 0
            var recordsCount = post["recordsCount"] as?  Int ?? 0

            if likesCount == 0 { // First like for the post

               // add self in posts_likes > postId > likes
               // increment likes count & increment records Count
                Api.Posts_Likes.firstPostsLikes(postId: postId)
                likesCount += 1
                recordsCount += 1
            }
            else {
                Api.Posts_Likes.setPostsLikes(postId: postId, onSuccess: { (isPostLiked) in  // checks if user liked the post or not, if he did, his id was added in posts_likes > likes

                    if isPostLiked {
                        likesCount += 1
                        recordsCount += 1
                    }
                    else {
                        likesCount -= 1
                        recordsCount -= 1
                    }

                }, onError: { (errMessage) in
                    onError(errMessage)
                })
            }

            post["recordsCount"] = recordsCount as AnyObject?
            post["likesCount"] = likesCount as AnyObject?

            currentData.value = post

            return TransactionResult.success(withValue: currentData)
        }
        return TransactionResult.success(withValue: currentData)
    })
    { (error, committed, snapshot) in
        if let error = error {
            onError(error.localizedDescription)
        }
        if let dict = snapshot?.value as? [String: Any] {
            let post = Post.transformDataToImagePost(dictionary: dict, key: snapshot!.key)
            onSuccess(post)
        }
    }
}

当用户再次单击该按钮时,它将进入else语句,因为likesCount不再等于0。这是它不起作用的地方。当Api.Posts_Likes.setPostsLikes(postId: postId, onSuccess:)被调用时,它应该返回一个Bool值,无论用户是否喜欢或不喜欢该帖子。基于该bool值,它应该increment或节点中decrementlikesCount& 。但它没有,我不明白为什么。recordsCountposts

  func firstPostsLikes(postId: String) {
        guard let currentUser = Api.Users.CURRENT_USER else { return }

    REF_POSTS_LIKES.child(postId).child("likes").child(currentUser.uid).setValue(true)

}

func setPostsLikes(postId: String, onSuccess: @escaping (Bool) -> Void, onError: @escaping (_ errorMessage: String?) -> Void) {

    let postLikesRef = Api.Posts_Likes.REF_POSTS_LIKES.child(postId)
    guard let currentUser = Api.Users.CURRENT_USER else { return }
    var userLikedPost: Bool = false

    postLikesRef.runTransactionBlock ({ (currentPostsLikesData) -> TransactionResult in

        if var postLikes = currentPostsLikesData.value as? [String : AnyObject] {
            var likes = postLikes["likes"] as? [String : Bool] ?? [:]

            if let _ = likes[currentUser.uid] {
                // Unlike the post and remove self from likes
                likes.removeValue(forKey: currentUser.uid)
                userLikedPost = false
            }
            else {
                // Like the post, add self to posts_likes, increase likesCount & recordsCount
                likes[currentUser.uid] = true
                userLikedPost = true
            }

            postLikes["likes"]  = likes as AnyObject

            currentPostsLikesData.value = postLikes

            return TransactionResult.success(withValue: currentPostsLikesData)
        }
        return TransactionResult.success(withValue: currentPostsLikesData)
    })
    { (error, committed, snapshot) in
        if let error = error  {
            onError(error.localizedDescription)
        }
            onSuccess(userLikedPost)
    } 

这是看起来的FirebaseDatabase样子:

在此处输入图像描述

recordsCount节点中的是、和的posts总和。在单元格中加载新内容时,我唯一需要显示的是. 这就是为什么我不想把所有喜欢、鼓掌、评论等的数组放在帖子本身下面,因为它会免费下载大量数据,除非用户点击按钮来实际commentsCountlikesCountrepostsCountapplaudsCountpostrecordsCountrecordsCount

标签: swiftfirebasefirebase-realtime-database

解决方案


推荐阅读