How to increment the value in specific node with firebase realtime database ios

Sharker

New Member
#1
Here i'm working in a chat application, i want to maintain the unread count for the recipient side. My json structre in console looks like
Mã:
user_history
|
|--> user_a_uuid
    |-> last_msg
    |-> last_msg_timestamp
    |-> unread_count
the scope of this question is, how to increment the value of unread_count. Prior incrementing i have the user_a_uuid and the node user_history & unread_count as a constant. So i tried as follows
Mã:
dbRef.child("user_history")
     .child(user_a_uuid)
     .child("unread_count")
     .runTransactionBlock { (unreadCount) -> TransactionResult in
        var value = unreadCount.value as? Int

        if value == nil {
            value = 0
        }

        unreadCount.value = value! + 1
        return TransactionResult.success(withValue: unreadCount)
}
I tried to follow the doc. But the thing is that, i don't want to run transaction on the root node as in the doc. I want to run the transaction only on the unread_count doc.

Problem I'm facing:

After attempting this code, the problem i face is that, unread_count node getting deleted as soon and while i return the TransactionResult inside the completion block, it added unread_count. The problem is that the value is not incremented due to unread_count getting deleted. It always stays to 1.

Thanks in advance.
 

Admin

Administrator
Thành viên BQT
#2
It appears you want to increment a counter stored in a node without affecting the other items in the node. Based on the information in the question there doesn't appear to be a need to use a transaction block in this use case due to the count being stored in code.
Prior incrementing i have the user_a_uuid and the node user_history & unread_count as a constant
I believe this means you're storing unread_count in a variable in code so if that's correct, it simply needs to be incremented in code and written to the node.

Starting with a duplicate structure:
Mã:
user_history
   uid_0
      last_msg: "some message"
      last_msg_timestamp: "20181028075700"
      unread_count: 2
and now we've added another message. The var needs to be incremented and then the corresponding node in Firebase need to be updated with the new value. Here's the code that does that:
Mã:
func updateMsgCount() {
   self.unread_count += 1 //this is a class var or however it's stored in code
   let unreadCountRef =  self.ref.child("user_history").child("uid_0").child("unread_count")
   unreadCountRef.setValue(self.unread_count)
Suppose however, that the unread_count is not stored in code but only stored in Firebase. Here's the code to read in the unread_count node, increment the count and store it back in Firebase.
Mã:
func updateCount() {
   let unreadCountRef = self.ref.child("user_history").child("uid_0").child("unread_count")
   unreadCountRef.observeSingleEvent(of: .value, with: { snapshot in
      var currentCount = snapshot.value as? Int ?? 0
      currentCount += 1
      unreadCountRef.setValue(currentCount)
   })
}
If you really need a transaction block, here's one to accomplish the same thing
Mã:
func updateCountTransactionStyle() {
    let unreadCountRef = self.ref.child("user_history").child("uid_0").child("unread_count")
    unreadCountRef.runTransactionBlock( { (currentData: MutableData) -> TransactionResult in

        var currentCount = currentData.value as? Int ?? 0
        currentCount += 1
        currentData.value = currentCount

        return TransactionResult.success(withValue: currentData)
    })
}
 
Top