如何在firebase中保存用户分数并在Android studio中实时检索它
我正在创建一个应用程序,其中单击按钮时点数会增加,并且这些点数应保存到 firebase.我设法将这些数据保存到 firebase.但是当我销毁我的应用程序并再次打开它时,点值显示相同但在单击按钮后.又是从0开始.
I am creating an app in which points increases on button click and those points should be saved to firebase. I managed to save those data to firebase. But when I destroy my app and open it again the points value is showing same but after clicking button. It again starts from 0.
例如:每次单击按钮时,点值都会增加到 10 点.现在,当我完全销毁应用程序并再次打开它时,点值显示相同,但是当再次单击按钮时,它会从初始状态开始.
For example: every time on button click the points value increases to 10 points. Now when I completely destroy the app and open it again, the points value shows same, but when button clicked it again starts from initial condition.
这是我的代码
int amount = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
button_claim.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
amount = amount + 100;
textView_points.setText(String.valueOf(amount));
databaseReference.setValue(textView_points.getText().toString());
}
});
}
@Override
protected void onStart() {
super.onStart();
if (mAuth.getCurrentUser() == null) {
finish();
Intent main = new Intent(this,MainActivity.class);
main.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(main);
}
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
textView_points.setText(dataSnapshot.getValue(String.class));
databaseReference.setValue(textView_points.getText().toString());
}
@Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(Main2Activity.this,"error",Toast.LENGTH_LONG).show();
}
});
}
在销毁应用程序之前请看图片,在销毁应用程序并上传到数据库之前点击按钮会增加积分请看图1
再次打开应用(关闭后)它显示相同的更新点请参见图 2
现在当我点击声明它返回到 100请参见图片编号 3
请帮我解决这个问题,我是新手谢谢
please help me on this problem, and i am a newbie Thanks
Edit: 29th, June 2020
现在不使用事务也可以解决这个问题.我们可以简单地使用以下方法增加一个值:
Now it's also possible to solve this problem without the use of a transaction. We can simply increment a value using:
rootRef.child("score").setValue(ServerValue.increment(1));
对于 decremenet,需要以下代码行:
And for decremenet, the following line of code is required:
rootRef.child("score").setValue(ServerValue.increment(-1));
这是在 Firebase 数据库中设置值的方式:
This is how you set a value in your Firebase database:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.child("score").setValue(1);
假设你的score
字段是Integer类型的,要解决这个问题,请使用以下方法:
Assuming that the your score
field is of type Integer, to solve this, please use the following method:
public static void setScore(String operation) {
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference scoreRef = rootRef.child("score");
scoreRef.runTransaction(new Transaction.Handler() {
@Override
public Transaction.Result doTransaction(MutableData mutableData) {
Integer score = mutableData.getValue(Integer.class);
if (score == null) {
return Transaction.success(mutableData);
}
if (operation.equals("increaseScore")) {
mutableData.setValue(score + 1);
} else if (operation.equals("decreaseScore")){
mutableData.setValue(score - 1);
}
return Transaction.success(mutableData);
}
@Override
public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {}
});
}
为此,我建议您绝对使用transactions
.如果用户同时尝试增加/减少分数,您将避免错误的结果.因此,作为结论,请根据您的增减操作调用此方法.
For this, I recommend you definitely use transactions
. You will avoid wrong results if users are trying to increase/decrease the score in the same time. So as a conclusion, call this method accordingly to your increase/decrease operation.
阅读方式如下:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference scoreRef = rootRef.child("score");
ValueEventListener eventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Integer score = ds.getValue(Integer.class);
Log.d("TAG", score + "");
}
@Override
public void onCancelled(DatabaseError databaseError) {}
};
scoreRef.addListenerForSingleValueEvent(eventListener);