Wilson Wilson
Wilson Wilson

Reputation: 3757

How to order items from Streambuilder

I'm creating a simple app using Cloud Firestore where I type in text and it gets added to a list.

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  TextEditingController _txtCtrl = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: SafeArea(
          child: Column(
            children: <Widget>[
              Container(
                  child: Row(children: <Widget>[
                Expanded(child: TextField(controller: _txtCtrl)),
                SizedBox(
                    width: 80,
                    child: OutlineButton(
                        child: Text("Add"),
                        onPressed: () {
                          Firestore.instance
                              .collection('messages')
                              .document()
                              .setData({'message': _txtCtrl.text});
                        })),
              ])),
              Container(
                height: 400,
                child: StreamBuilder<QuerySnapshot>(
                  stream: Firestore.instance.collection('messages').snapshots(),
                  builder: (BuildContext context,
                      AsyncSnapshot<QuerySnapshot> snapshot) {
                    if (snapshot.hasError)
                      return new Text('Error: ${snapshot.error}');
                    switch (snapshot.connectionState) {
                      case ConnectionState.waiting:
                        return new Text('Loading...');
                      default:
                        return new ListView(
                          children: snapshot.data.documents
                              .map((DocumentSnapshot document) {
                            return new ListTile(
                              title: new Text(document['message']),
                            );
                          }).toList(),
                        );
                    }
                  },
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

Everything works perfectly, but the list of items in the Streambuilder get randomly arranged.

I know that this is because the data in the list is getting mapped by the .map function (Because a map has no order).

How can I display the items in the order by which they are added to my database in a StreamBuilder without calling the .map function?

Upvotes: 4

Views: 2154

Answers (1)

Ali Bayram
Ali Bayram

Reputation: 7941

Add timestamp when you setData to the document;

Firestore.instance.collection('messages').add({
  'message': _txtCtrl.text,
  'timestamp': FieldValue.serverTimestamp(),
});

And use orderBy when you fetch data; Firestore.instance.collection('messages').orderBy('timestamp').snapshots();

Upvotes: 7

Related Questions