Firebase数据库如何增加一个整数值

12

在我的数据库中递增一个int值,我首先通过监听器获取该值,将其加1,然后将新值设置为数据库。这种方法可行,但我想知道是否有更简单的方法。这种方式似乎太麻烦了。


1
这是正确的方式。 - Ognian Gloushkov
3
不要描述你的代码,而是分享最小化可重现问题的代码 - Frank van Puffelen
3个回答

21

更新:自2020年初以来,实际上已经有一种服务器端操作可以增加实时数据库中的值。请参阅dfeverx在此问题上的答案,或者我的Q&A比较事务和递增之间的性能:您可以多快地对Firebase实时数据库中的值进行原子递增?


Firebase数据库没有服务器端增加值(或执行其他计算)的方法。

您的方法是一种实现递增的方式,但可能会导致竞争条件。

  1. 数据库中的值为12
  2. 客户机1读取值为12
  3. 客户机2读取值为12
  4. 客户机1写入其递增值13
  5. 客户机2写入其递增值13

结果现在可能不正确(这取决于您的用例)。

在这种情况下,一种使其正常工作的方法是使用Firebase事务,将读取和写入组合成单个函数。

事务在Firebase数据库文档中有详细介绍。强烈建议阅读它。花费几个小时在那里将避免未来很多问题。从文档中可以了解到:

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);
    }
});

21

从Firebase JavaScript SDK v7.14.0开始,您可以使用ServerValue.increment()在Firebase中增加值。

方法1

var userRef= firebase.database().ref("user/user_id_123");
userRef.push({
  likes: firebase.database.ServerValue.increment(1)
});

方法二

firebase.database()
    .ref('user')
    .child('user_id_123')
    .child('likes')
    .set(firebase.database.ServerValue.increment(1))

您还可以将浮点数或负值传递给增量函数。

您可以在这里找到参考链接:https://firebase.google.com/docs/reference/js/v8/firebase.database.ServerValue


0

Kotlin 版本:

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")
    }
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接