es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

El método .limit() de Firestore es lo suficientemente inteligente como para detectar el límite de nuevos datos en función de la variable entera variable.

Tengo un StatefulWidget que contiene un widget Future.Builder y un método controlador de escucha en Listview.builder de la siguiente manera

class Messages extends StatefulWidget {

  const Messages({Key? key,}) : super(key: key);

  @override
  _MessagesState createState() => _MessagesState();
}

class _MessagesState extends State<messages> {

  int limit = 10;

  @override
  void initState() {
    controller!.addListener(listener);
    super.initState();
  }

  listener() {
    if (controller!.offset >= controller!.position.maxScrollExtent && !controller!.position.outOfRange) {
      setState(() {
        limit = limit+10;
      });
    }
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      body: FutureBuilder(
        future: FirebaseFirestore.instance.collection("users").limit(limit).get(),
        builder: (context , AsyncSnapshot<querysnapshot> messages) {
          if (!messages.hasData) {
            return Center(
              child: circulearProgress(),
            );
          }
          return ListView.builder(
            controller: controller,
            itemCount: messages.data!.docs.length,
            itemBuilder: (context , int index) {

              DocumentSnapshot documentSnapshot = messages.data!.docs[index];

              return Text(documentSnapshot['textMessage']);
            },
          );
        },
      ),
    );
  }
}

Ahora bien, .get() obtendrá 10 documentos por defecto y también manejo el oyente para aumentar 10 en la variable limit una vez que el usuario desplaza hacia abajo la página y el flujo obtiene otros 10 documentos además de los anteriores 10 documentos antiguos… Ahora la pregunta es

¿.get() leerá solo los nuevos 10 documentos cada vez que el usuario desplace hacia abajo o leerá de nuevo los 10 documentos anteriores junto con los nuevos 10?

Si no lo hace, ¿cómo puedo evitar leer los documentos antiguos nuevamente en mi ejemplo?

Cualquier edición a mi código con una muestra de solución será agradecida.

Saludos cordiales.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El método get() leerá tanto los últimos 10 documentos anteriores como los nuevos 10 documentos cada vez que se active el listener, no solo los nuevos 10 documentos. Para evitar leer los documentos antiguos nuevamente, puedes usar una consulta startAfter() con el último documento snapshot que recibiste de la llamada anterior a get(). Así es como puedes modificar tu código para lograr esto:

    1. Crea una variable de tipo DocumentSnapshot para almacenar el último documento snapshot que recibiste:
    DocumentSnapshot? lastDocument;
    
    1. Reemplaza la consulta get() con una consulta startAfter() que comienza después del último documento snapshot, si existe:
    FutureBuilder(
      future: (lastDocument == null)
          ? FirebaseFirestore.instance.collection("users").limit(limit).get()
          : FirebaseFirestore.instance
              .collection("users")
              .startAfterDocument(lastDocument!)
              .limit(limit)
              .get(),
      builder: (context, AsyncSnapshot<querysnapshot> messages) {
        // ...
    
    1. Establece el valor de lastDocument al último documento snapshot que recibas:
    itemBuilder: (context, int index) {
      DocumentSnapshot documentSnapshot = messages.data!.docs[index];
      if (index == messages.data!.docs.length - 1) {
        lastDocument = documentSnapshot;
      }
      return Text(documentSnapshot['textMessage']);
    },
    

    De esta manera, la consulta startAfter() solo obtendrá los nuevos documentos después del último documento snapshot que recibiste, sin incluir los documentos antiguos que ya recibiste en la llamada anterior a get().

Comments are closed.