skip to Main Content

I’m using GroupListView on Flutter to show messages from Firestore, where I grouped my messages by the message sent date with descending order. Although the messages are grouped as I wanted, Flutter can’t seem to sort the groups correctly by their date format.

Is there any solution for this?

enter image description here

Here is the code I used:

// list of messages in chatroom
showMessages() {
  return StreamBuilder(
    stream: chats,
    builder: (context, AsyncSnapshot snapshot) {
      return snapshot.hasData
        ? GroupedListView(
          reverse: true,
            elements: snapshot.data.docs, 
            groupBy: (QueryDocumentSnapshot<Object?>? document) =>
              DateFormat.yMMMMd().format(DateTime.fromMillisecondsSinceEpoch(document?.get('messageCreatedTime'))),
            order: 
              GroupedListOrder.DESC,
            groupSeparatorBuilder: (value) => 
              Container(
                margin: EdgeInsets.symmetric(
                  horizontal: MediaQuery.of(context).size.width * 0.4, 
                  vertical: 10),
                padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 2),
                decoration: BoxDecoration(
                  color: Colors.grey.shade100,
                  borderRadius: BorderRadius.circular(12)
                ),
                child: Text(
                  value.toString(), 
                  // convertTimeToString(value),
                  style: greySmall, textAlign: TextAlign.center)
              ),
            itemBuilder: (context, elements) =>
              MessageTile(
                messageText: elements!['messageText'], 
                messageSentTime: elements['messageCreatedTime'], 
                sentByMe: elements['messageSenderId'] == DatabaseService().getCurrentUserId(),
              )
            )
        : Container();
    }
  );
}

2

Answers


  1. Chosen as BEST ANSWER

    I found a temporary solution by changing the dateformat used on groupBy to DateFormat.yMd()

    here is the updated code

    showMessages() {
      return StreamBuilder(
        stream: chats,
        builder: (context, AsyncSnapshot snapshot) {
          return snapshot.hasData
    
            ? GroupedListView(
              reverse: true,
                elements: snapshot.data.docs, 
                groupBy: (QueryDocumentSnapshot<Object?>? document) =>
                    DateFormat.yMd().format(DateTime.fromMillisecondsSinceEpoch(document?.get('messageCreatedTime'))),
                order: 
                  GroupedListOrder.DESC,
                groupSeparatorBuilder: (value) => 
                  Container(
                    margin: EdgeInsets.symmetric(
                      horizontal: MediaQuery.of(context).size.width * 0.4, 
                      vertical: 10),
                    padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 2),
                    decoration: BoxDecoration(
                      color: Colors.grey.shade100,
                      borderRadius: BorderRadius.circular(12)
                    ),
                    child: Text(
                      value,
                      style: greySmall, textAlign: TextAlign.center)
                  ),
    
                itemBuilder: (context, elements) =>
                  MessageTile(
                    messageText: elements!['messageText'], 
                    messageSentTime: elements['messageCreatedTime'], 
                    sentByMe: elements['messageSenderId'] == DatabaseService().getCurrentUserId(),
                  )
                )
            : Container();
        }
      );
    }
    

  2. Here is the updated code:

    showMessages() {
      return StreamBuilder(
        stream: chats,
        builder: (context, AsyncSnapshot snapshot) {
          return snapshot.hasData
            ? GroupedListView(
              reverse: true,
                elements: snapshot.data.docs, 
                groupBy: (QueryDocumentSnapshot<Object?>? document) =>
                  DateTime.fromMillisecondsSinceEpoch(document?.get('messageCreatedTime')),
                order: 
                  GroupedListOrder.DESC,
                groupComparator: (DateTime value1, DateTime value2) =>
                  value2.compareTo(value1),
                groupSeparatorBuilder: (value) => 
                  Container(
                    margin: EdgeInsets.symmetric(
                      horizontal: MediaQuery.of(context).size.width * 0.4, 
                      vertical: 10),
                    padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 2),
                    decoration: BoxDecoration(
                      color: Colors.grey.shade100,
                      borderRadius: BorderRadius.circular(12)
                    ),
                    child: Text(
                      DateFormat.yMMMMd().format(value), 
                      style: greySmall, textAlign: TextAlign.center)
                  ),
                itemBuilder: (context, elements) =>
                  MessageTile(
                    messageText: elements!['messageText'], 
                    messageSentTime: elements['messageCreatedTime'], 
                    sentByMe: elements['messageSenderId'] == DatabaseService().getCurrentUserId(),
                  )
                )
            : Container();
        }
      );
    }
    

    by the code I’ve used, you are grouping by DateTime.fromMillisecondsSinceEpoch not DateFormat at first.

    happy coding…

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