How to convert serverTimestamp to String when using StreamBuilder

Issue

What I want

To order ListView based on server timestamp

My code

Adding to firestore collection:

onPressed: () {
FirebaseFirestore.instance.collection('things').add(
  {
    // some code
    'timestamp': FieldValue.serverTimestamp(),
  },
);

Get data from the firestore and ordered them based on the server timestamp

return StreamBuilder<QuerySnapshot>(
  stream: FirebaseFirestore.instance.collection('things').orderBy('timestamp').snapshots(),

Expected behavior

List View are displayed ordered based on the server timestamp

What I got

This error:

Expected a value of type ‘String’, but got one of type ‘Timestamp’

What I’ve tried

I’ve tried adding toString() when sending the data to the firestore: 'timestamp': FieldValue.serverTimestamp().toString(), but then the data on the firestore didn’t store timestamp, instead they stored FieldValue(Instance of 'FieldValueWeb').

I know that I probable have to convert them to String when I’m getting the data from the firestore, but I have no idea how to do that. I’ve tried adding in toString() when getting the data into the stream as such:

stream: FirebaseFirestore.instance.collection('things').orderBy('timestamp').toString().snapshots()

but then it shows below error and won’t compile.

The method ‘snapshots’ isn’t defined for the type ‘String’.

The official document does not say anything about converting them to String either.

If anybody knows how to solve this please help me, I’m really stuck here.


Full StreamBuilder and ListView code

return StreamBuilder<QuerySnapshot>(
  stream: _firestore.collection('things').orderBy('timestamp').snapshots(),
  builder: (context, snapshot) {
    List<Text> putDataHere = [];

    final things = snapshot.data.docs;
    for (var thing in things) {
      final myData = Map<String, String>.from(thing.data());
      final myThing = myData['dataTitle'];
      final thingWidget = Text(myThing);
      putDataHere.add(thingWidget);
    }
    return Expanded(
      child: ListView(
        children: putDataHere,
      ),
    );
  },
);

Solution

The problem was totally different from what I had initially thought.

I honestly forgot that when I retrieve the data from the Firestore to process it, I set my Map to Map<String, String>, it was fine before because I only had String, but now that I have Timestamp type, it doesn’t work.

The answer to the question is just simply changing the Map<String, String> to Map<String, dynamic>

Answered By – Sae

Answer Checked By – Candace Johnson (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *