For incrementing an int value in my database , I first get that value by using a listener , increment it by 1 and then set the new value to database. This works but I want to know if there is an easier way of doing this. This way seems like too much work.
-
1This is the way to go – Ognian Gloushkov Nov 03 '16 at 15:17
-
3Don't describe your code, but share the [minimal code that reproduces the problem](http://stackoverflow.com/help/mcve). – Frank van Puffelen Nov 03 '16 at 15:18
3 Answers
Update: since early 2020 there actually is a server-side operation to increment values in the Realtime Database. See dfeverx's answer on this, or my own Q&A comparing performance between transactions and increments: How quickly can you atomically increment a value on the Firebase Realtime Database?.
There is no server-side way to increment values (or do other calculations) in the Firebase Database.
Your approach is one way of doing this, but it has the chance of leading to a race condition.
- the value in the database is 12
- client 1 reads the value 12
- client 2 read the value 12
- client 1 writes its incremented value 13
- client 2 writes its incremented value 13
The result is now likely incorrect (it depends on your use-case).
In that case, one way to make it work is to use Firebase transactions, which combine the reading and writing into a single function.
Transactions are covered in the Firebase Database documentation. I highly recommend reading it. A few hours spent there will prevent many problems down the road. From the docs:
postRef.runTransaction(new Transaction.Handler() {
@Override
public Transaction.Result doTransaction(MutableData mutableData) {
Long value = mutableData.getValue(Long.class);
if (value == null) {
mutableData.setValue(0);
}
else {
mutableData.setValue(value + 1);
}
return Transaction.success(mutableData);
}
@Override
public void onComplete(DatabaseError databaseError, boolean b,
DataSnapshot dataSnapshot) {
Log.d(TAG, "transaction:onComplete:" + databaseError);
}
});

- 565,676
- 79
- 828
- 807
From firebase JavaScript SDK v7.14.0 you can use ServerValue.increment()
to increment value in firebase
Method 1
var userRef= firebase.database().ref("user/user_id_123");
userRef.push({
likes: firebase.database.ServerValue.increment(1)
});
Method 2
firebase.database()
.ref('user')
.child('user_id_123')
.child('likes')
.set(firebase.database.ServerValue.increment(1))
You can also pass float or negative value to the increment function
You can find the reference here: https://firebase.google.com/docs/reference/js/v8/firebase.database.ServerValue
Kotlin Version:
val ref = Firebase.database.reference
.child("users")
.child(postId)
.child("likes")
ref.runTransaction(object : Transaction.Handler {
override fun doTransaction(mutableData: MutableData): Transaction.Result {
val value = mutableData.getValue(Long::class.java)
if (value == null) {
mutableData.value = 0
} else {
mutableData.value = value + 1 // to decrement - mutableData.value = value - 1
}
return Transaction.success(mutableData)
}
override fun onComplete(error: DatabaseError?, committed: Boolean, currentData: DataSnapshot?) {
if (error != null) {
println("transaction-onCompleteError: ${error.message}")
}
val currentCount = currentData?.getValue(Long::class.java) ?: 0L
println("currentCount: $currentCount")
}
})

- 17,576
- 18
- 108
- 256