Pierre Louet
Pierre Louet

Reputation: 25

For flutter while using firebase, how can you organize a collection by timetamp when embedded in a map and reading from a streambuilder

I am trying to use a streambuilder to read a list of messages (maybe show the 5 most recent), and would like to organize them by timestamp. As you can see the documents are different categories, by the end there will be a few hundred documents, as well as collections and don't wish to make a few hundred collections (left side collection if looking at firestore database as opposed to right collection where I show the message info).

I am writing to the documents this way:

   try {
            _firestore.collection('court_feed').doc('category3').set({
            '${DateTime.now().millisecondsSinceEpoch}': {
            'posterUID': '${user?.uid}',
            'posterDisplayName': user?.displayName,
            'content': postContent,
        }

When reading from firestore I have a simple stream that looks like this:

_firestore.collection('court_feed').doc(category3).snapshots()

If using a futurebuilder I could just grab the entire document and organize the maps that way, its not very clean though.

Knowing that I would like to organize these by categories as shown, how can I organize all of these messages by time?

enter image description here

Upvotes: 0

Views: 116

Answers (1)

Rohit Kharche
Rohit Kharche

Reputation: 2919

Based on your DB snapshot and your code snippet it looks like you are storing messages inside the documents using Map but using ${DateTime.now().millisecondsSinceEpoch} as a Map name.

As your current structure will not scale because you are storing data as Nested data in documents

Your current db structure will also not give you sorted result instead you can save the documents as an subcollection named messages and use ${DateTime.now().millisecondsSinceEpoch} as an document id to create your messages something like follows:

Firestore Database
└── court_feed - (Collection)
    └── {category3} - Document Id
        └── messages - (sub-collection)
            ├── {DateTime.now().millisecondsSinceEpoch} - Document Id
            │   ├── posterUID : string
            │   ├── posterDisplayName : string
            │   └── content : string
            └── {DateTime.now().millisecondsSinceEpoch} - Document Id
                ├── posterUID : string
                ├── posterDisplayName : string
                └── content : string

Using a structure like this will help you to get the documents order by ${DateTime.now().millisecondsSinceEpoch} as follows :

_firestore
    .collection('court_feed')
    .doc('category3')
    .collection('messages')
    .orderBy(FieldPath.documentId()) // 👈 we can order based on this now
    .snapshots()

Now to write the new message in the DB you can follow the following snippet :

var category = 'category3';
var documentId = DateTime.now().millisecondsSinceEpoch.toString();

_firestore
    .collection('court_feed')
    .doc(category)
    .collection('messages')
    .doc(documentId) // 👈 set a new document id as DateTime.now().millisecondsSinceEpoch
    .set({
      'posterUID': '${user?.uid}',
      'posterDisplayName': user?.displayName,
      'content': postContent,
    })

Reference : Subcollections

Upvotes: 2

Related Questions