How to display all data in array?

Viewed 113

I'm trying to display data from an array in firestore. I displayed it, but only [0] in the array is showing. I'm trying to get all the data in the array to show.

builder: (_, AsyncSnapshot<List<DocumentSnapshot>> snapshot){
        if(snapshot.hasData){
        return ListView.builder(
          itemCount: snapshot.data!.length,
          itemBuilder: ((_, index) {
            List<Widget> tiles = [];
            
            for (Map post in snapshot.data![index]['posts']) {
              tiles.add(
                Expanded(
                  child: Container(
                    margin: EdgeInsets.all(2),
                    padding: EdgeInsets.all(1),
                    decoration: BoxDecoration(border:  Border.all(color:Colors.black)),
                    child: Center(
                      child: ListTile(
                        title: Text(post['postText'], style: TextStyle(color: Colors.white),),
                        subtitle: Text(post['fromUser'], style: TextStyle(color: Colors.white),),
                      ),
                    ),
                  ),
                )
              );
            }
            return Expanded(
              child: ListView(
             
               children: tiles,
              ),
            );
          }),  
        );
        }
        else{
          return Center(child: CircularProgressIndicator(),);
        }
      },

enter image description here

enter image description here

enter image description here

enter image description here

2 Answers

Edit

To answer your qn about newest to oldest:

I suggest you put a FieldValue.timestamp field in your group chat documents! Then, you can order them like this:

  Future<List<DocumentSnapshot>> getDoc(groupID) async {
    var firestore = FirebaseFirestore.instance;
    QuerySnapshot qn = await firestore.collection('groups')
    .where('groupChatId', isEqualTo: groupID)
    .orderBy('timestamp', descending: true)  // <- Here!
    .get();
    return qn.docs;
  }

(All of that I copied by hand, since you hadn't provided this code as text, as I asked you to!... )

If you don't have a timestamp field, there is a way to still find out when a document was created... but I don't know how. Plus, in this case, I guess you want the time a certain FIELD was created in the document...! I don't know if that's possible. In fact, for that you'll probably have to do:

    List<Map> posts = snapshot.data![index]['posts'];

    // Sort list according to the 'date' field in each Map in the list:
    posts.sort((mapA, mapB){
      return mapA['date'].compareTo(mapB['date']);
    });  

   // Then you'll use posts in your for-loop instead of snapshot.data![index]['posts']:
    
    for (Map post in posts) {
      tiles.add( /*etc*/);
    }

Btw, if you want it to update when new messages come in, you can do like this:

import 'dart:async';

// Put the below in the State of a StatefullWidget:

  StreamSubscription<QuerySnapshot<Map<String, dynamic>>>? qn;
  List<DocumentSnapshot>? eventDocs;

  void getDocStream(groupID) async {
    var firestore = FirebaseFirestore.instance;
    qn = firestore.collection('groups')
        .where('groupChatId', isEqualTo: groupID)
        .orderBy('timestamp', descending: true)
        .snapshots().listen((event) {
      // Put here everything you want to happen when new things happen in the stream!
      // For example:
      setState(() {
        eventDocs = event.docs;
      });
      // Now, you can use eventDocs instead of getDoc(groupID), as you did before.
      // Just remember that it will be null at first!
    });
  }

  @override
  void dispose() {
    if (qn != null) qn!.cancel();  // This is to prevent the stream from going on, after you've left the page or even closed the app...
    super.dispose();
  }

Old answer:

But you're telling it to display only post [0]!...

If there are more posts in each document, and you want to display all of them, you need to make a for-loop or something. For example:

    itemBuilder: ((_, index) {
      List<Widget> tiles = [];

      for (Map post in snapshot.data![index]['posts']) {
        tiles.add(
            ListTile(
              title: Text(post['postText']),
              subtitle: Text(post['fromUser']),
            ));
      }

      return Expanded(
        child: Column(
          children: tiles,
        ),
      );
    }),

And btw... Next time you ask a qn, plz paste your code as text rather than an image! So that we can copy-paste it into our answer, rather than having to retype it from the image. It's so easy to make a mistake and then you get an error coz we didn't copy it right.

try this

title: Text(snapshot.data![index]['posts']['postText']),
Related