¿Cómo configurar addSnapshotListener y eliminar en populateViewHolder en el elemento RecyclerView?
Lo he implementado RecyclerView
con la biblioteca FirebaseUI-Android .
Mis RecyclerView
datos en tiempo real cambian bien una vez que los uso.FirebaseRecyclerAdapter
En la Colección, ese documento de datos tiene un tipo de campo como booleano, entero, referencia .
Quiero usar esa referencia para obtener datospopulateViewHolder
addSnapshotListener
.
¡Ayúdame! Aquí está mi código:
FirebaseRecyclerAdapter<Conv, ConvViewHolder> firebaseConvAdapter = new FirebaseRecyclerAdapter<Conv, ConvViewHolder>(
Conv.class,
R.layout.users_single_layout,
ConvViewHolder.class,
conversationQuery
) {
@Override
protected void populateViewHolder(final ConvViewHolder convViewHolder, final Conv conv, int i) {
final String list_user_id = getRef(i).getKey();
final DocumentReference docRef = db.collection("cities").document(list_user_id);
docRef.addSnapshotListener(new EventListener<DocumentSnapshot>() {
@Override
public void onEvent(@Nullable DocumentSnapshot snapshot,
@Nullable FirebaseFirestoreException e) {
if (e != null) {
Log.w(TAG, "Listen failed.", e);
return;
}
if (snapshot != null && snapshot.exists()) {
Log.d(TAG, "Current data: " + snapshot.getData());
} else {
Log.d(TAG, "Current data: null");
}
}
});
}
};
mConvList.setAdapter(firebaseConvAdapter);
Firebase dice que si agrega addSnapshotListener, debe eliminarlo una vez, no es necesario separar un oyente
Cuando ya no esté interesado en escuchar sus datos, debe desconectar su oyente para que dejen de recibir llamadas de eventos. Esto permite que el cliente deje de usar ancho de banda para recibir actualizaciones. Puede utilizar la función de cancelación de suscripción
onSnapshot()
para dejar de escuchar las actualizaciones.
Para lograr esto, necesitas usar algo EventListener<DocumentSnapshot>
como este:
EventListener<DocumentSnapshot> eventListener = new EventListener<DocumentSnapshot>() {
@Override
public void onEvent(DocumentSnapshot snapshot, FirebaseFirestoreException e) {
if (snapshot != null && snapshot.exists()) {
//Do what you need to do
}
}
};
Declare una ListenerRegistration listenerRegistration;
variable global y agregue SnapshotListener en el lugar donde sea necesario, así:
if (listenerRegistration == null ) {
listenerRegistration = yourRef.addSnapshotListener(eventListener);
}
Para eliminar el oyente, simplemente use las siguientes líneas de código en su onStop()
método:
@Override
protected void onStop() {
if (listenerRegistration != null) {
listenerRegistration.remove();
}
}
Además, no olvide agregarlo nuevamente una vez que onStart()
se llame a su método.
@Override
protected void onStart() {
super.onStart();
listenerRegistration = yourRef.addSnapshotListener(eventListener);
}
Cuando llama addSnapshotListener
para escuchar actualizaciones en tiempo real , significa que adjunta un oyente al que se llama para cada cambio que se produce en su base de datos. Esto también sucede cuando tu aplicación está cerrada, por eso es obligatorio desconectar a los oyentes. antes de que se destruya la actividad.
Si en su aplicación no necesita obtener los datos en tiempo real, simplemente puede usar una llamada get() directamente en la referencia, que solo lee el documento una sola vez. Dado que solo se lee una vez, no es necesario eliminar ningún oyente. Este es el corresponsal deaddListenerForSingleValueEvent()
utilizado en la base de datos en tiempo real de Firebase.
También hay una forma más elegante de eliminar el oyente que es pasar la actividad como primer argumento en el método addSnapshotListener() , para que Firestore pueda limpiar los oyentes automáticamente cuando se detiene la actividad.
ListenerRegistration lg = yourDocumentRef
.addSnapshotListener(YourActivity.this, eventListener);
También hay una forma más elegante de eliminar el oyente que es pasar la actividad como primer argumento en el método addSnapshotListener(), para que Firestore pueda limpiar los oyentes automáticamente cuando se detiene la actividad. cita en bloque
Fue muy importante. No busqué "forma elegante", pero fue una pista de por qué mi oyente se detiene a veces. Eliminé el campo de actividad y ahora el oyente no se detiene sin mis instrucciones directas en caso de que cambie el estado de la actividad.