Reputation: 25
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) {
}
} );
Upvotes: 1
Views: 964
Reputation: 598728
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
}
} );
Upvotes: 3
Reputation: 1470
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.
Upvotes: 1