【问题标题】:Firebase ,Swift: `runTransactionBlock()` returns nullFirebase,Swift:`runTransactionBlock()` 返回 null
【发布时间】:2017-01-19 12:13:07
【问题描述】:

每次我运行 runTransactionBlock 它都会给我 null,虽然那个位置有一个节点:-

FIRMutableData(最顶层交易)(空)

在线:-print(totalPost)

func updateTotalNoOfPost(){


    let prntRef = FIRDatabase.database().reference().child("TotalPosts")
    prntRef.observeSingleEventOfType(.Value, withBlock: {(totalSnap) in

        if totalSnap.exists(){

            prntRef.child("noOfTotalPost").runTransactionBlock({ (totalPost: FIRMutableData) -> FIRTransactionResult in

                print(FIRAuth.auth()!.currentUser!.uid)//Giving me correct userID 
                print(totalPost)//<Null>
                print(prntRef.child("noOfTotalPost"))//Giving me correct path to that node 

                totalPost.value = totalPost.value as! Int + 1
                return FIRTransactionResult.successWithValue(totalPost)
                }, andCompletionBlock: { (err, TF, snap) in

                    print(err?.localizedDescription)
                    print(TF)
                    print(snap!.value)
                    FIRTransactionResult.abort()// Am i using this right?
            })
        }else{

            prntRef.setValue(["noOfTotalPost": 1])

        }
    })
}

我的 JSON 树结构是这样的:-

 {
  "TotalPosts" : {
    "noOfTotalPost" : 1
     },
   "Users" : {
    "FBLXPOxBomakPCQuDTilGC7Becu2" : {...},
     "1DASWPOxBomakPCdasd1d123au6" : {...},...}}

我正在为我的数据库使用默认安全规则:-

      {
       "rules": {
          ".read": "auth != null",
          ".write": "auth != null"

        }
      }

我只想在任何用户创建帖子时增加noOfTotalPost 子节点的值:-

我已经有了使用observeSingleEventOfType. 的解决方法:

    let prntRef = FIRDatabase.database().reference().child("TotalPosts")
    prntRef.child("noOfTotalPost").observeSingleEventOfType(.Value, withBlock: {(totalSnap) in

        if totalSnap.exists(){

            if let tNo = totalSnap.value as? Int{

               prntRef.child("noOfTotalPost").setValue(tNo+1)//Working Fine

             }
          })
        }else{

            prntRef.setValue(["noOfTotalPost": 1])

        }
    })

但不知道为什么runTransactionBlock 不起作用!

【问题讨论】:

  • 您的区块最初会以null 触发的预期行为。如果该位置已经有一个值,它应该使用来自服务器的当前值再次触发。如果该更新存在冲突,它将再次触发,等等。所以一定要处理nil(可能到那时将计数设置为0)。
  • 如果这确实解释了您看到的行为,那么这个问题与 stackoverflow.com/questions/28811037/… 重复
  • @FrankvanPuffelen 谢谢,解决了。是的,给定的链接确实解释了基本概念,但是您可以在此处发布带有代码的答案吗?

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


【解决方案1】:

正如@Frank 在 cmets 中所说,runTransactionBloack 的预期行为最初会返回 NSNull,但如果该位置已经有一个值,它将再次被触发。如果有更新值有冲突,会再次触发。

代码:-

func updateTotalNoOfPost(completionBlock : (() -> Void)){


    let prntRef = FIRDatabase.database().reference().child("TotalPosts")

    prntRef.child("noOfTotalPost").runTransactionBlock({ (noOfPosts) -> FIRTransactionResult in
        if let totalPost = noOfPosts.value as? Int{

            noOfPosts.value = totalPost + 1
            return FIRTransactionResult.successWithValue(noOfPosts)
        }else{

            return FIRTransactionResult.successWithValue(noOfPosts)

        }
        }, andCompletionBlock: {(error,completion,snap) in

                print(error?.localizedDescription)
                print(completion)
                print(snap)
            if !completion {

                print("The value wasn't able to Update")
                }else{

                completionBlock()
            }
    })

}

对于基本概念:-

Data in transaction is null

【讨论】:

    猜你喜欢
    • 2016-10-06
    • 2017-02-07
    • 2018-08-19
    • 2017-08-26
    • 1970-01-01
    • 2021-09-28
    • 2020-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多