Изменение значения в Firebase приводит к бесконечному циклу - PullRequest
1 голос
/ 11 июля 2020

Я хочу реализовать функцию «добавить в избранное», нажав звездочку (кнопку). Когда я нажимаю в первый раз, устанавливаю значение в избранное пользователя в firebase, и звездочка будет желтой, а когда я нажимаю еще раз, она удаляется из списка и звездочка возвращается в нормальное состояние. Я пробую этот код, но зацикливаюсь. Как я могу это решить?

    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) {

                }
            } );

Ответы [ 2 ]

3 голосов
/ 11 июля 2020

Поскольку вы вызываете addValueEventListener, Firebase вызывает ваш onDataChange с текущими данными как можно быстрее, а затем продолжает отслеживать изменения в базе данных. Всякий раз, когда происходит изменение, он снова вызывает ваш onDataChange с обновленными данными.

В вашем onDataChange агрегате вы изменяете данные, вызывая setValue. Поскольку эти данные находятся в том месте, которое вы слушаете, они запускают слушателя, который снова вызывает ваш onDataChange. Таким образом, вы получите al oop of onDataChange -> setValue -> onDataChange -> setValue ....

. Самое простое решение - использовать addListenerForSingleValueEvent, которое дает только начальное значение и не слушает. Таким образом, вы получите onDataChange -> setValue и ничего больше.

В коде:

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
        }
    } );
1 голос
/ 11 июля 2020

Вам нужно использовать addListenerForSingleValueEvent вместо addValueEventListener.

  • addValueEventListener - который продолжает перечислять события постоянно .
  • addListenerForSingleValueEvent - слушает только самое первое событие .

В вашем коде просто замените addValueEventListener на addListenerForSingleValueEvent, вот и все, оставшуюся часть кода оставьте нетронутой .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...