java - Android studio/Firebase - 尝试获取数据时遇到无限循环
问题描述
我正在尝试从我的 firebaseDB 中获取数据,但它一直在无限运行,我不明白为什么。
问题:用户键入要汇款的邮件。我从数据库中提取所有用户,并将书面电子邮件与每个用户的电子邮件进行比较。如果电子邮件与用户匹配(电子邮件是唯一的),则在内部进行另一个 db 调用,获取收件人的余额。用户的余额被更新,接收者的余额也是如此。问题是它不断地为发件人减去金额,并不断地为收件人添加金额(通过单击一次)。
我知道这与异步执行有关,但我对编程太陌生,不知道如何解决它。
任何人都可以帮忙吗?下面的代码:
public void sendTo(){
final String receiverEmail = editTextReciever.getText().toString().trim();
String amountHolder = ediTextAmount.getText().toString().trim();
if(TextUtils.isEmpty(receiverEmail)){
Toast.makeText(getApplicationContext(), "Enter an email", Toast.LENGTH_LONG).show();
return;
}
if(TextUtils.isEmpty(amountHolder)){
Toast.makeText(getApplicationContext(), "Enter an amount to send", Toast.LENGTH_LONG).show();
return;
}
//If it has gotten this far, theres data in the editText (the editText can only contain numbers)
final int amount = Integer.parseInt(amountHolder);
//Looping through every user in the DB and checking if the typed email belong to any of the users in the DB
FirebaseDatabase.getInstance().getReference("users").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
User user = snapshot.getValue(User.class);
//If typed email matches a user in the db (emails are unique due to firebaseAuthentication), continue
if(user.getEmail().equals(receiverEmail)){
recipientUid = snapshot.getKey();
if(accountBalance - amount >= 0 && uid != snapshot.getKey()){
//I have to fetch our the balance of the user i'm sending money to so I can add the amount to his balance
FirebaseDatabase.getInstance().getReference("Accounts/" + accountType).child(snapshot.getKey()).child("balance").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
int balanceOfReceiver = Integer.parseInt(dataSnapshot.getValue().toString());
int updatedBalance = balanceOfReceiver + amount;
//The senders balance is updated
accountBalance = accountBalance - amount;
FirebaseDatabase.getInstance().getReference("Accounts/" + accountType).child(uid).child("balance").setValue(accountBalance);
//And the recipients balance is updated
FirebaseDatabase.getInstance().getReference("Accounts/" + accountType).child(recipientUid).child("balance").setValue(updatedBalance);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
} else {
Toast.makeText(getApplicationContext(), "You can't overdraw or send money to yourself", Toast.LENGTH_LONG).show();
}
}
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
解决方案
You add ValueEventListener to the users ref and onDataChange is called when ever data changes. You subtract the money amount and by that triggering the onDataChange again and you get in to a loop.
you need to rethink your code structure or remove the listener before you change the money amount.
this
FirebaseDatabase.getInstance().getReference("Accounts/" + accountType).child(uid).child("balance").setValue(accountBalance);
FirebaseDatabase.getInstance().getReference("Accounts/" + accountType).child(recipientUid).child("balance").setValue(updatedBalance);
trigger this
public void onDataChange(@NonNull DataSnapshot dataSnapshot)
推荐阅读
- android - 华为 HMS Maps Android Codelab 不工作
- python - 将函数的可选参数设置为列表
- arrays - 在批处理数组中使用变量作为索引失败
- android - 如何解决“com.android.support:appcompat-v7:28.0.0”
- python - 动态窗口上的滚动总和
- python - 无论我使用什么回归模型,我都会获得负 R^2
- javascript - Node.js 对象承诺
- jenkins - 每个阶段的 Jenkins 多个帖子部分
- swift - 如何拆分 NSToolbarItem
- postgresql - Postgres 自动完成和全文搜索