【问题标题】:Voting: Vote registers twice [closed]投票:投票登记两次[关闭]
【发布时间】:2019-08-15 09:40:25
【问题描述】:

我正在制作一个投票系统。但是,当您投票然后删除投票时,分数会上升 1,然后下降 2。如果您随后尝试投反对票,则分数根本不会移动。我认为代码将删除赞成票记录为反对票,但我不知道为什么。切换您的投票会使预期的 2 分摇摆到得分上。除非您投票,否则请离开 viewController,然后切换您的投票。这只会给你1分的投票变化。

    @IBOutlet weak var checkbox: Checkbox!
    @IBOutlet weak var downVote: Checkbox!
    var boxcheck = false
    var downcheck = false
    var postRef:DatabaseReference{
    return Database.database().reference().child("posts").child("comments")}
 }
      func set(comment:Comment) {
    commentLabel.text = comment.text
    upvoteCountLabel.text = String(comment.upvotes)
    downcheck = UserDefaults.standard.bool(forKey: "\(comment.snap) downvotes")
    boxcheck = UserDefaults.standard.bool(forKey: "\(comment.snap) upvotes")
    downVote.isChecked = UserDefaults.standard.bool(forKey: "\(comment.snap) downvotes")
    checkbox.isChecked = UserDefaults.standard.bool(forKey: "\(comment.snap) upvotes")

    downcheck = UserDefaults.standard.bool(forKey: "\(comment.snap) downvotes")
    boxcheck = UserDefaults.standard.bool(forKey: "\(comment.snap) upvotes")
    func voteUp() {
        self.postRef.child(comment.postID).child(comment.snap).child("upvotes").runTransactionBlock({ (currentData:MutableData)  -> TransactionResult in
            if (currentData.value as? [String: AnyObject]) == nil {

                let upvotesNumber = comment.upvotes
                var upvotes = upvotesNumber
                upvotes += 1

                currentData.value = upvotes

                return TransactionResult.success(withValue: currentData)
            }

            //Abort like if there was a problem
            print("abortion")
            return TransactionResult.abort()

        })

    }
  func voteDown(){
        self.postRef.child(comment.postID).child(comment.snap).child("upvotes").runTransactionBlock({ (currentData:MutableData)  -> TransactionResult in
            if (currentData.value as? [String: AnyObject]) == nil {

                let upvotesNumber = comment.upvotes
                var upvotes = upvotesNumber
                upvotes -= 1

                currentData.value = upvotes

                return TransactionResult.success(withValue: currentData)
            }

            //Abort like if there was a problem
            print("abortion")
            return TransactionResult.abort()

        })
    }

    checkbox.valueChanged = { (value) in
        print("checkbox value change: \(value)")

      self.boxcheck = self.checkbox.isChecked
        UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
        UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
        if self.checkbox.isChecked == true && self.downVote.isChecked == true{
            voteUp()
            self.boxcheck = self.checkbox.isChecked
        }
        if self.checkbox.isChecked == true && self.downVote.isChecked == false{

        UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
        UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")

            voteUp()
            self.boxcheck = self.checkbox.isChecked
        }

       if self.checkbox.isChecked == false && self.downVote.isChecked == false{
        UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
        UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")

           voteDown()
        self.downVote.isChecked = false
        self.boxcheck = self.checkbox.isChecked
        self.downcheck = self.downVote.isChecked
        }

       if self.checkbox.isChecked == false && self.downVote.isChecked == true{
           voteDown()
        self.boxcheck = self.checkbox.isChecked
        }
            if self.downVote.isChecked == true && self.checkbox.isChecked == true {
            self.downVote.isChecked = false
            self.downcheck = self.downVote.isChecked
            }

        print("POSTITIVE My current downcheck value is \(self.downcheck)")
        print("POSITIVE My current upcheck value is \(self.boxcheck)")
        UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
        UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
    }


    downVote.valueChanged = { (value) in
        self.downcheck = self.downVote.isChecked
        print("downVote value change: \(value)")
        UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
        UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
        if self.checkbox.isChecked == true && self.downVote.isChecked == true {
            voteDown()
            self.downcheck = self.downVote.isChecked

        }
        if self.checkbox.isChecked == false && self.downVote.isChecked == true {

        UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
        UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")

            voteDown()
            self.downcheck = self.downVote.isChecked
        }

        if self.checkbox.isChecked == false && self.downVote.isChecked == false{
        UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
        UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
           voteUp()
            self.downcheck = self.downVote.isChecked
            self.boxcheck = self.checkbox.isChecked
        }
     if self.checkbox.isChecked == true && self.downVote.isChecked == false   {
        UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
        UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
                voteUp()
        self.downcheck = self.downVote.isChecked
            }

            if self.checkbox.isChecked == true && self.downVote.isChecked == true {
            self.checkbox.isChecked = false
            self.boxcheck = self.checkbox.isChecked
        }
        UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
        UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
    }
    print("My current downcheck value is \(self.downcheck)")
    print("My current upcheck value is \(self.boxcheck)")
}


}

Firebasse 引用工作正常,但如果您好奇,这是我的评论模型:

import Foundation

class Comment: Equatable {
static func == (lhs: Comment, rhs: Comment) -> Bool {
    return lhs.id == rhs.id
}


var snap:String
var id:String
var text:String
var reports: Int
var upvotes: Int
var postID: String
init(id: String, text:String, reports:Int, snap: String, upvotes: Int, postID: String) {
    self.id = id
    self.text = text
    self.reports = reports
    self.snap = snap
    self.upvotes = upvotes
    self.postID = postID
}

还有 Firebase JSON:

   {
  "posts" : {
    "-Lku3osQQXgagYMVI9ua" : {
      "commentsNumber" : 2,
      "reports" : 1,
      "text" : "Hey",
      "timestamp" : 1564342439656,
      "title" : "Welcome to Librex",
      "upvotes" : 1,
      "userID" : "mMqFhoNiR3gWiTd7J4wtPABhtYB3"
    }
    "comments" : {
      "-Lku3osQQXgagYMVI9ua" : {
        "-LlcJ_6Kus1nuqaCk17R" : {
          "comment_by_uid" : "N3HNT1aVkPXhiCRu9fzJknWYxCt2",
          "comment_text" : "This is really cool; thanks!",
          "reports" : 0,
          "upvotes" : 3
        },
        "-Llhr2E7UodiuyvzeGMi" : {
          "comment_by_uid" : "N3HNT1aVkPXhiCRu9fzJknWYxCt2",
          "comment_text" : "K ",
          "reports" : 0,
          "upvotes" : 1

          }
        }
       }
     }
   }

【问题讨论】:

  • 为什么要检查 currentData 是否为 nil? if (currentData.value as? [String: AnyObject]) == nil。在访问它之前,您应该检查以确保它不是 nil。见Save Data As Transaction
  • 嗯...当我将其更改为 if (currentData.value as? [String: AnyObject]) == nil 时,没有投票通过。我通过阅读文档获得了此代码。我相信你,但我不确定发生了什么
  • 除非我忽略了某些东西,否则这种逻辑是没有意义的。整个想法是您要验证 currentData.value 不为零,以便您可以对其进行读写。如果为 nil,则应用程序将崩溃。我不确定您在文档中的何处看到该代码 - 如果您查看我对文档的评论中的链接,您可以清楚地看到在使用它之前是否检查了不是 nil; if var post = currentData.value as? [String : AnyObject],另外,你评论中的代码和我指出的一样,所以你没有做任何改变。
  • 对不起,我的意思是if (currentData.value as? [String: AnyObject]) != nil { 使代码不更新值。于是我取出了 if 语句,然后打印了 currentData.value 是什么,得到了 Optional(0)
  • 您的代码正在执行以下操作;如果 currentData.value 为 nil,表示节点不存在,则写入一些数据。如果存在,什么也不做。这也意味着如果该节点以前不存在,则将创建该节点,并将其值设置为 comment.upvotes。因此,您认为代码在做什么,并不是它实际上在做的事情,这可能就是您没有得到预期结果的原因。

标签: ios swift firebase firebase-realtime-database voting


【解决方案1】:

这是我用于投票的代码!

 func voteUp() {
        self.postRef.child(comment.postID).child(comment.snap).child("upvotes").runTransactionBlock({
            (currentData: MutableData!) in

            //value of the counter before an update
            var value = currentData.value as? Int

            //checking for nil data is very important when using
            //transactional writes
            if value == nil {
                value = 0
            }

            //actual update
            currentData.value = value! + 1
            UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
            UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
            return TransactionResult.success(withValue: currentData)

        }, andCompletionBlock: {
            error, commited, snap in

            //if the transaction was commited, i.e. the data
            //under snap variable has the value of the counter after
            //updates are done
            if commited {
                let upvotes = snap?.value as! Int

            } else {
                UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
                UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
                TransactionResult.abort()
            }
        })

    }

  func voteDown(){
    self.postRef.child(comment.postID).child(comment.snap).child("upvotes").runTransactionBlock({
        (currentData: MutableData!) in

        //value of the counter before an update
        var value = currentData.value as? Int
        UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
        UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
        //checking for nil data is very important when using
        //transactional writes
        if value == nil {
            value = 0
            UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
            UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
        }

        //actual update
        UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
        UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
        currentData.value = value! - 1
        return TransactionResult.success(withValue: currentData)
    }, andCompletionBlock: {
        error, commited, snap in

        //if the transaction was commited, i.e. the data
        //under snap variable has the value of the counter after
        //updates are done
        if commited {
            let upvotes = snap?.value as! Int
            UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
            UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
        } else {

            TransactionResult.abort()
            UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
            UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
        }
    })

    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-15
    • 1970-01-01
    • 1970-01-01
    • 2019-04-03
    • 1970-01-01
    • 1970-01-01
    • 2012-10-29
    • 2012-07-14
    相关资源
    最近更新 更多