skip to Main Content

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


  1. try this

    title: Text(snapshot.data![index]['posts']['postText']),
    
    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search