简体   繁体   English

Android studio / Firebase - 试图获取数据的无限循环

[英]Android studio/Firebase - hitting an infinite loop trying to fetch data

I'm trying to fetch data from my firebaseDB but it keeps going infinitely and I can't see why. 我正在尝试从我的firebaseDB中获取数据,但它一直在无限地进行,我看不出原因。

The problem: User types a mail to send money to. 问题:用户键入邮件来汇款。 I pull out all the users from the db and compare the written email to the email of each user. 我从数据库中提取所有用户,并将写入的电子邮件与每个用户的电子邮件进行比较。 If the email matches an user (the emails are unique), another db call is made inside, getting the balance of the recipient. 如果电子邮件与用户匹配(电子邮件是唯一的),则在内部进行另一次数据库调用,获取收件人的余额。 The balance of the user is updated and so is it for the recipient. 用户的余额已更新,收件人也是如此。 The problem is that it keeps subtracting the amount for the sender and keeps adding for the recipient infinitely (by clicking once). 问题是它不断减去发件人的金额,并不断为收件人添加(通过点击一次)。

I know this has something to do with it being executed asynchronous, but I'm too new to programming to know how to solve it. 我知道这与异步执行有关,但我对编程很新,不知道如何解决它。

Can anyone help? 有人可以帮忙吗? Code below: 代码如下:

    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. 您将ValueEventListener添加到用户ref,并在数据更改时调用onDataChange。 You subtract the money amount and by that triggering the onDataChange again and you get in to a loop. 你减去金额,再次触发onDataChange然后你进入一个循环。

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) 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM