安卓:Firebase数字递增

4

我在使用Java和Firebase制作值的增量时遇到了问题,它无法更新全局变量。当我在onStart处调用EventListener时,它成功地显示了变量的正确值(60)。但是,在我想通过按钮单击将其增加10时,它会显示0。

long value;

@Override
protected void onStart() {
    super.onStart();

    final TextView mValue = (TextView) findViewById(R.id.some_textview);

    mRef = new Firebase(some_correct_url);
    mRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            value = (long) dataSnapshot.getValue();
            mValue.setText(value+"");
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {

        }
    });
}

当用户点击按钮时,将调用以下函数。
public void addTen(View view) {
    mRef = new Firebase(my_private_url);
    mRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            value =(long) dataSnapshot.getValue();
            value = value + 10;
        }
        @Override
        public void onCancelled(FirebaseError firebaseError) {
        }
    });

    mRef.setValue(value);

}

总的来说,第一部分检索了变量的正确值,但第二部分没有增加正确的值。提前感谢!
编辑:顺便说一下,我将Firebase规则设置如下:
{
"rules": {
".read": "true",
".write": "true"
}
}

这是关于开发时间的。


你说的“不增加”是什么意思?你有打印日志或更新UI的值吗? - Kathi
是的,我正在调试它的值,并且在onStart的第一部分中似乎是正确的,但在addTen函数的第二部分中它采用了全局初始化为零值的情况。 - user5718928
它增加了,但起始值错误。它从零开始,但应该从60(来自Firebase的值)开始。 - user5718928
也许这个问题已经在这里得到解决了:https://stackoverflow.com/questions/44102312/how-to-increment-number-in-firebase - Diego Venâncio
3个回答

6
Firebase监听器以异步方式触发。在监听器触发并更新value之前,您对mRef.setValue(value)的调用将执行。请按如下更改您的代码:
public void addTen(View view) {
    mRef = new Firebase(my_private_url);
    mRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            value =(long) dataSnapshot.getValue();
            value = value + 10;
            dataSnapshot.getRef().setValue(value);
        }
        @Override
        public void onCancelled(FirebaseError firebaseError) {
        }
    });
}

请注意,addListenerForSingleValueEvent()取代了addValueEventListener()。我认为你不想在每次调用addten()时堆叠监听器。

它仍然从0开始增量,但我明白你的意思。 - user5718928
@MichaelJancen-Widmer:针对您的帖子,您用 some_correct_urlmy_private_url 替换了真实的 URL。您确定真实的 URL 是相同的吗? - Bob Snyder
是的,它们是这样的,这只是为了保护隐私。 - user5718928
所以,听众在 onStart() 中返回60,在相同位置的 addTen() 中返回0。我被难住了。 - Bob Snyder
没错。我认为它在addTen()函数里得到了60,但是没有将值返回给全局变量"value"。那只是我的猜测。 - user5718928
显示剩余3条评论

0
在Firestore中,您可以使用以下方法(也可以使用减少方法)来增加值:
void updateIMEICount(){
    progressDialog.setMessage(getString(R.string.verifying_imei_dialog_message));
    progressDialog.show();

    firebaseFirestore.collection(Constants.FB_IMEI_ROOT_PATH).document("IMEI").get()
            .addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
                @Override
                public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                    if (task.isSuccessful()) {
                        DocumentSnapshot documentSnapshot = task.getResult();
                        final IMEIModel imeiModel = documentSnapshot.toObject(IMEIModel.class);
                        Log.d(TAG, "documentSnapshot imeiModel : " + imeiModel.toString());
                        final IMEIModel imeiModelUpdate = new IMEIModel();
                        imeiModelUpdate.setIMEI(imeiModel.getIMEI()+1);
                        documentSnapshot.getReference().set(imeiModelUpdate).addOnCompleteListener(new OnCompleteListener<Void>() {
                            @Override
                            public void onComplete(@NonNull Task<Void> task) {
                                progressDialog.dismiss();
                                Log.d(TAG,"imeiModelUpdate updated from : "+imeiModel.getIMEI());
                                Log.d(TAG,"imeiModelUpdate updated to : "+imeiModelUpdate.getIMEI());
                                launchHomeScreen();
                            }
                        }).addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                progressDialog.dismiss();
                            }
                        });

                        progressDialog.dismiss();

                    } else {
                        utility.failureToast("getting call id failed .please try again");
                        progressDialog.dismiss();
                        Log.d(TAG, "getting getCallID failed");
                    }
                }
            });
}

0

答案已经被标记为正确,但如果两个用户在同一时间进行相同的操作会发生什么?

请参考将数据保存为 Firebase 事务

当处理可能被并发修改破坏的数据时,例如增量计数器,您可以使用事务操作。

例如,在社交博客应用程序示例中,您可以允许用户对帖子进行点赞和取消点赞,并按如下方式跟踪帖子收到的点赞数量:

private void onStarClicked(DatabaseReference postRef) {
    postRef.runTransaction(new Transaction.Handler() {
        @Override
        public Transaction.Result doTransaction(MutableData mutableData) {
            Post p = mutableData.getValue(Post.class);
            if (p == null) {
                return Transaction.success(mutableData);
            }

            if (p.stars.containsKey(getUid())) {
                // Unstar the post and remove self from stars
                p.starCount = p.starCount - 1;
                p.stars.remove(getUid());
            } else {
                // Star the post and add self to stars
                p.starCount = p.starCount + 1;
                p.stars.put(getUid(), true);
            }

            // Set value and report transaction success
            mutableData.setValue(p);
            return Transaction.success(mutableData);
        }

        @Override
        public void onComplete(DatabaseError databaseError, boolean b,
                               DataSnapshot dataSnapshot) {
            // Transaction completed
            Log.d(TAG, "postTransaction:onComplete:" + databaseError);
        }
    });
}

所以你的方法可能会被两个用户同时进行的并发修改破坏


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