首页 > 解决方案 > 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) {

        }
    });
}

标签: javaandroidfirebasefirebase-authentication

解决方案


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) 

推荐阅读