¿Cómo configurar addSnapshotListener y eliminar en populateViewHolder en el elemento RecyclerView?

Resuelto Pankaj Savaliya asked hace 54 años • 2 respuestas

Lo he implementado RecyclerViewcon la biblioteca FirebaseUI-Android .

Mis RecyclerViewdatos 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 datospopulateViewHolderaddSnapshotListener .

¡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.

Pankaj Savaliya avatar Jan 01 '70 08:01 Pankaj Savaliya
Aceptado

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 addSnapshotListenerpara 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);
Alex Mamo avatar Feb 09 '2018 09:02 Alex Mamo

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.

Dzmitry Sotnikov avatar Aug 20 '2019 14:08 Dzmitry Sotnikov