问题
Every time i run runTransactionBlock
it Gives me null, Although there is a node at that location:-
FIRMutableData (top-most transaction) (null)
at the line :- 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])
}
})
}
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"
}
}
All i want is to increment a noOfTotalPost
child node's value every time any user creates a post:-
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])
}
})
But cant figure out why runTransactionBlock
wont work!
回答1:
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:-
Data in transaction is null
来源:https://stackoverflow.com/questions/39443839/firebase-swift-runtransactionblock-returns-null