在 Firebase 中自动增加一个值

Posted

技术标签:

【中文标题】在 Firebase 中自动增加一个值【英文标题】:Auto-increment a value in Firebase 【发布时间】:2015-05-09 01:21:48 【问题描述】:

如何从 android 客户端自动增加存储在 Firebase 中的值?

目前:我声明int id = 1。当我增加时,我看到值 2、3 等被存储。没关系,但是当我重新运行项目时,id 再次设置为等于 1。

我希望它表现得像一个静态变量,所以我可以创建一个从 1 变为无穷大的 id 而无需重置。

更新失败

我使用以下方法将 Firebase 引用和一个字符串传递给函数 incrementCounter。

if(language_chosen.equalsIgnoreCase("english"))
 
   Firebase publRef = f.child("Language").child("English").child("Message");
   Firebase newPublRef = publRef.push();
   writeMsgActivity demo = new writeMsgActivity();
   demo.incrementCounter(newPublRef,the_msg_enter);                                 
  

现在我尝试在 oncomplete 方法中使用 public void incrementCounter(Firebase publref,String my_msg) 处传递的引用和字符串,但它给了我一个错误。

   public void incrementCounter(Firebase publref,String my_msg) 
    publref.runTransaction(new Transaction.Handler() 
        @Override
        public Transaction.Result doTransaction(final MutableData currentData) 
            if (currentData.getValue() == null) 
                currentData.setValue(1);
             else 
                currentData.setValue((Long) currentData.getValue() + 1);
            

            return Transaction.success(currentData);
        

        public void onComplete(FirebaseError firebaseError, boolean committed, DataSnapshot currentData) 
            if (firebaseError != null) 
                System.out.println("Firebase counter increment failed.");
             else 
                System.out.println("Firebase counter increment succeeded.");

                Map<String, Object> publ = new HashMap<String, Object>();
                publ.put("pubMsg", my_msg);
                publ.put("id",currentData);
                publref.setValue(publ);
            
        
    );

更新已解决

                final Firebase upvoteref = new Firebase("https://shareurday.firebaseio.com/Message/"+msg_id+"/upvotes"); 

            upvoteref.runTransaction(new Transaction.Handler() 
                @Override
                public Transaction.Result doTransaction(final MutableData currentData) 
                    if (currentData.getValue() == null) 
                        currentData.setValue(1);
                     else 
                        currentData.setValue((Long) currentData.getValue() + 1);
                    
                    return Transaction.success(currentData);
                

                public void onComplete(FirebaseError firebaseError, boolean committed, DataSnapshot currentData) 
                    if (firebaseError != null) 
                        System.out.println("Firebase counter increment failed.");
                     else 
                        System.out.println("Firebase counter increment succeeded.");
                    
                
            );

变量 msg_id 是从 push 中随机生成的 id。

【问题讨论】:

我不确定您在 Firebase 中使用了什么代码以及 Reload 在这里意味着什么?但是,如果您在重新加载时调用相同的函数(设置 id=1),您将获得 id 1。您必须在某些文件/数据库中设置 id 并在该存储中不断更新。 我可以在数据库中设置它,但每次我重新运行程序时它都会重置为整数 id=1 在每次运行时,您需要检查文件/db 中是否存在...如果不存在则插入 ELSE UPDATE 。你的 Q 看起来很通用,但是如果对象/记录是共享的,你需要跟踪所有并发更改。 【参考方案1】:

这是一个增加单个计数器的示例方法。关键思想是您要么创建条目(将其设置为 1),要么 mutating 现有条目。在这里使用事务可以确保如果多个客户端尝试同时增加计数器,所有请求最终都会成功。来自 Firebase 文档(重点是我的):

在处理复杂数据时使用我们的事务功能可能会被并发更新破坏

public void incrementCounter() 
    firebase.runTransaction(new Transaction.Handler() 
        @Override
        public Transaction.Result doTransaction(final MutableData currentData) 
            if (currentData.getValue() == null) 
                currentData.setValue(1);
             else 
                currentData.setValue((Long) currentData.getValue() + 1);
            

            return Transaction.success(currentData);
        

        @Override
        public void onComplete(FirebaseError firebaseError, boolean committed, DataSnapshot currentData) 
            if (firebaseError != null) 
                Log.d("Firebase counter increment failed.");
             else 
                Log.d("Firebase counter increment succeeded.");
            
        
    );

【讨论】:

你能告诉我如何传递变量吗,我不擅长这个。 您到底想达到什么目的?如果您使用push 保存数据,它会自动生成一个唯一的 id,并且不需要您手动增加计数器。参见例如firebase.com/docs/android/guide/saving-data.html#section-push 。让我知道这是否对您来说是一个更好的解决方案。 我需要为每条消息创建一个 id,以便我可以在回复中与另一棵树进行比较。 (我已经完成了这部分)例如。每个 msg 都有一个 id,并且对该 msg 的每个回复都将使用该 msg 的 id。所以当我检索回复时,它将在 msg id 中。 您尝试过publ.put(currentData, my_msg);,正如我之前所说的那样吗? 抱歉这么多麻烦,我得到它的工作,我会上传解决方案。它正盯着我的脸。非常感谢您的帮助!!!【参考方案2】:

Firestore 中添加了一项新功能,可自动增加值。就这么简单

document("fitness_teams/Team_1").
  updateData(["step_counter" : FieldValue.increment(500)])

参考链接: https://firebase.googleblog.com/2019/03/increment-server-side-cloud-firestore.html

在我的项目中使用下面的代码。

var firestore = Firestore.instance;
firestore.collection('student').document('attendance').updateData('total_attendace': FieldValue.increment(1));

【讨论】:

以上是关于在 Firebase 中自动增加一个值的主要内容,如果未能解决你的问题,请参考以下文章

Python:无法从函数中读取返回值

Uncaught FirebaseError: Firebase: No Firebase App '[DEFAULT]' has been created - 在 vue.js 中调用 Fireba

Stripe 和 Firebase:FirebaseError:collection() 的第一个参数应为 CollectionReference、DocumentReference 或 Fireba

Firebase 推送通知徽章计数是不是在 iOS 中自动增加?

异步箭头函数预期没有返回值

如何在后台监听firebase实时数据库更新事件并使用颤振自动启动应用程序(如Messenger中的调用功能)?