0

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!

Dravidian
  • 9,945
  • 3
  • 34
  • 74
  • It is expected behavior that your block will initially trigger with `null`. f there is already a value in the location, it should trigger again with the current value from the server. If there is a conflict on that update, it will trigger again, etc. So be sure to handle `nil` (probably by then setting the count to `0`). – Frank van Puffelen Sep 12 '16 at 19:16
  • If that indeed explains the behavior you see, this question is a duplicate of http://stackoverflow.com/questions/28811037/data-in-transaction-is-null – Frank van Puffelen Sep 12 '16 at 19:31
  • @FrankvanPuffelen Thanks , that solved it. Yes, the given link does explain the underlying concept, but can you post an answer with code here? – Dravidian Sep 12 '16 at 22:22

1 Answers1

2

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

Community
  • 1
  • 1
Dravidian
  • 9,945
  • 3
  • 34
  • 74