1

I have a field stored within a document in Firestore called 'lastChecked' which is of type timestamp. I want to retrieve this data and display it in my list view.builder. I am using this code:

ListTile(
      title: Text('${data.docs[index]['name']}'),
      subtitle: Text(data.docs[index]['lastChecked'].toString()),

in place of toString() I have also tried toDate() but this is not recognised.

With the current code as above, I am returned

Timestamp(seconds=xxxxx, nanoseconds=xxxxx) within my list.

This is the full code segment showing my Stream of QuerySnapshots, Streambuilder, and ListView.builder.

   Stream<QuerySnapshot> bags = FirebaseFirestore.instance
        .collection("bags")
        .where("station", isEqualTo: thisUserBase)
        .snapshots();

// scaffold app bar etc within this space //

 child: StreamBuilder<QuerySnapshot>(
              stream: bags,
              builder: (
                BuildContext context,
                AsyncSnapshot<QuerySnapshot> snapshot,
              ) {
                if (snapshot.hasError) {
                  return Text('Error!');
                }

                if (snapshot.connectionState == ConnectionState.waiting) {
                  return CircularProgressIndicator();
                }

                final data = snapshot.requireData;

                return ListView.builder(
                  itemCount: data.size,
                  itemBuilder: (context, index) {
                    return Padding(
                      padding: const EdgeInsets.all(5.0),
                      child: Card(
                        elevation: 5,
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(8),
                        ),
                        child: data.docs[index]['isChecked']
                            ? null
                            : ListTile(
                                title: Text('${data.docs[index]['name']}'),
                                subtitle: Text(
                                    data.docs[index]['lastChecked'].toString()),
                                trailing: data.docs[index]['isChecked']
                                    ? greenCircle
                                    : redCircle,
                              ),
                      ),
                    );
                  },
                );
              },
            ),

All help gratefully received!

Thanks

EDIT AFTER RESPONSES - this is my current code that gives me the error:

return ListView.builder(
                  itemCount: data.size,
                  itemBuilder: (context, index) {
                    var timestamp = data.docs[index]['lastChecked'];
                    var date =
                        DateTime.fromMicrosecondsSinceEpoch(timestamp * 1000);
                    String formatted = DateFormat('yyyy-MM-dd').format(date);

                    return Padding(
                      padding: const EdgeInsets.all(5.0),
                      child: Card(
                        elevation: 5,
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(8),
                        ),
                        child: data.docs[index]['isChecked']
                            ? null
                            : ListTile(
                                title: Text('${data.docs[index]['name']}'),
                                subtitle: Text(formatted),
                                trailing: data.docs[index]['isChecked']
                                    ? greenCircle
                                    : redCircle,
                              ),
                      ),
                    );
                  },
                );
              },
            ),
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
sd00148
  • 27
  • 3
  • Calling `toDate()` on the timestamp object is the right way to go. What isn't working when you do that? Can you show the code you tried for that, and the error message you got? I recommend checking out: https://stackoverflow.com/questions/56627888/how-to-print-firestore-timestamp-as-formatted-date-and-time/58309472#58309472 – Frank van Puffelen Oct 09 '22 at 13:45

2 Answers2

0

Try that:

   ListTile(
                                    title: Text('${data.docs[index]['name']}'),
                                    subtitle: Text(
                                       DateTime.fromMillisecondsSinceEpoch(data.docs[index]
['lastChecked'] * 1000)),
Shimaa Yasser
  • 587
  • 4
  • 12
0

First you need to convert your asdas to DateTime like this:

DateTime date = (data.docs[index]['lastChecked'] as Timestamp).toDate();

then use the intl package and format it to what ever you want:

String formatted = DateFormat('yyyy-MM-dd').format(date);

and now show formatted in your list:

ListTile(
   title: Text('${data.docs[index]['name']}'),
   subtitle: Text(formatted),
   trailing: data.docs[index]['isChecked']
                ? greenCircle
                : redCircle,
)

full example:

ListView.builder(
    itemCount: data.size,
    itemBuilder: (context, index) {
       DateTime date = (data.docs[index]['lastChecked'] as Timestamp).toDate();
       
       String formatted = DateFormat('yyyy-MM-dd').format(date);

       return Padding(
           padding: const EdgeInsets.all(5.0),
           child: Card(
               elevation: 5,
               shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(8),
               ),
               child: data.docs[index]['isChecked']
                    ? null
                    : ListTile(
                          title: Text('${data.docs[index]['name']}'),
                          subtitle: Text(formatted),
                          trailing: data.docs[index]['isChecked']
                                    ? greenCircle
                                    : redCircle,
                        ),
                      ),
                    );
                  },
                )

the result would be something like 2022/7/21.

eamirho3ein
  • 16,619
  • 2
  • 12
  • 23
  • thank you - I am unsure where to place the variables within my code. The Stream sits inside the build method for this page, but to access the data.docs[index] I need to be within my streamBuilder do I not? Therefore I can't work out where to declare the variables. Otherwise this makes sense - thank you! – sd00148 Oct 09 '22 at 13:19
  • I placed them within my ListView.Builder above its return statement, which works in the sense that I can access data.docs to declare the variables, but I get this error when I run it: The following NoSuchMethodError was thrown building: Class 'Timestamp' has no instance method '*'. Receiver: Instance of 'Timestamp' Tried calling: *(1000) – sd00148 Oct 09 '22 at 13:32
  • Check out my new update – eamirho3ein Oct 09 '22 at 13:37
  • thank you - check my new code snippet in question edited (at the bottom) - this looks to be exactly the same as yours and still gives me the error above! Any ideas? – sd00148 Oct 09 '22 at 13:41
  • could you please print('timestamp = ${data.docs[index]['lastChecked']}');? – eamirho3ein Oct 09 '22 at 13:47
  • it works! (Although in your answer you still have (date) in brackets when declaring the String formatted = ..... this should be (timestamp), otherwise it works perfectly - thanks again!! – sd00148 Oct 09 '22 at 13:53
  • I updated it multiple time, please see the last one. also glad to help. – eamirho3ein Oct 09 '22 at 13:56