Changing value in Firebase results in infinite loop

自闭症网瘾萝莉.ら 提交于 2020-07-23 07:38:21

问题


I want to implement a function of 'add to favorite' by clicking in a star (button). When i click for the first time, set a value to user favorite in firebase and the star will be yellow, and when i click again, it removes from list, and star back to normal. I'm tryin' this code, but is looping. How can i solve this?

    final DatabaseReference ref = FirebaseDatabase.getInstance().getReference( "Usuarios" );
    ref.child( mAuth.getUid() ).child( "Favoritos" )
            .addValueEventListener( new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                    if (dataSnapshot.exists()) {
                        botaoFavorito.setImageResource(  R.drawable.ic_favoritos  );
                        ref.child( mAuth.getUid() ).child( "Favoritos" ).child( posicao ).setValue(null);
         
                    }
              else {
                        botaoFavorito.setImageResource(  R.drawable.ic_favorito_adicionado  );
                        ref.child( mAuth.getUid() ).child( "Favoritos" ).child( posicao ).setValue(posicao);
                       
                    }
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {

                }
            } );

回答1:


You need to use addListenerForSingleValueEvent instead of addValueEventListener.

  • addValueEventListener - which goes on listing events continuously.
  • addListenerForSingleValueEvent- listens for the very first event only.

In your code, just replaceaddValueEventListener with addListenerForSingleValueEvent, that's all, leave the reamaining portion of the code intact.




回答2:


Since you're calling addValueEventListener, Firebase calls your onDataChange with the current data as quickly as possible, and then keeps monitoring the database for changes. Whenever there is a change, it calls your onDataChange again, with the updated data.

In your onDataChange implement, you modify the data by calling setValue. Since that data is under the location you're listening on, it triggers the listener, which calls your onDataChange again. So you get a loop of onDataChange -> setValue -> onDataChange -> setValue....

The simplest solution is to use addListenerForSingleValueEvent, which only gets the initial value and doesn't keep listening. So with that you get onDataChange -> setValue and nothing more.

In code:

final DatabaseReference ref = FirebaseDatabase.getInstance().getReference( "Usuarios" );
ref.child( mAuth.getUid() ).child( "Favoritos" )
    .addListenerForSingleValueEvent( new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

            if (dataSnapshot.exists()) {
                botaoFavorito.setImageResource(  R.drawable.ic_favoritos  );
                ref.child( mAuth.getUid() ).child( "Favoritos" ).child( posicao ).setValue(null);
 
            }
      else {
                botaoFavorito.setImageResource(  R.drawable.ic_favorito_adicionado  );
                ref.child( mAuth.getUid() ).child( "Favoritos" ).child( posicao ).setValue(posicao);
               
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            throw databaseError.toException(); // don't ignore errors
        }
    } );


来源:https://stackoverflow.com/questions/62844510/changing-value-in-firebase-results-in-infinite-loop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!