问题描述
每次我运行 runTransactionBlock
时,它都会给我 null ,尽管在该位置有一个节点:-
Every time i run runTransactionBlock
it Gives me null, Although there is a node at that location:-
在此行:-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树结构是这样的:-
My JSON tree struct is something like this:-
{
"TotalPosts" : {
"noOfTotalPost" : 1
},
"Users" : {
"FBLXPOxBomakPCQuDTilGC7Becu2" : {...},
"1DASWPOxBomakPCdasd1d123au6" : {...},...}}
我正在为数据库使用默认的安全规则:-
I am using default Security Rules for my DB:-
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
我想要的是每次任何用户创建帖子时都增加noOfTotalPost
子节点的值:-
All i want is to increment a noOfTotalPost
child node's value every time any user creates a post:-
我已经有了使用observeSingleEventOfType.
的解决方法:
I already have a workaround using 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
无法正常工作!
But cant figure out why runTransactionBlock
wont work!
推荐答案
正如@Frank在评论中所说, runTransactionBloack
的预期行为是最初返回NSNull
,但是如果已经有一个值会再次被触发.如果在更新值时发生冲突,则会再次触发.
As @Frank said in comments it's expected behaviour of runTransactionBloack
to return NSNull
initially , But if there already is a value in that location, it will get triggered again.And if there is a conflict in updating the value, It will trigger again.
代码:-
Code:-
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()
}
})
}
用于基础概念:-
For underlying concept:-
这篇关于Firebase,Swift:`runTransactionBlock()`返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!