我想通过单击星号(按钮)来实现“添加到收藏夹”功能。当我第一次单击时,在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) {
}
} );
答案 0 :(得分:3)
自从您调用addValueEventListener
以来,Firebase会尽快使用当前数据调用onDataChange
,然后继续监视数据库中的更改。只要有更改,它就会使用更新的数据再次调用您的onDataChange
。
在您的onDataChange
工具中,您可以通过调用setValue
来修改数据。由于该数据位于您正在监听的位置下,因此它将触发监听器,并再次调用您的onDataChange
。因此,您得到一个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 :(得分:1)
您需要使用addListenerForSingleValueEvent
而不是addValueEventListener
。
addValueEventListener
-持续连续列出事件。addListenerForSingleValueEvent
-聆听
仅第一个事件。在您的代码中,只需将addValueEventListener
替换为addListenerForSingleValueEvent
,仅需保留代码的其余部分即可。