Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter sort Firebase snapshot by timestamp

I'm trying to sort snapshot by timestamp but returns original order.
data structure looks like this enter image description here

I have two snapshot and timestamps are -1536025466539 and -1536025893015.
So, I expect -1536025893015 to come first after sorted. Does anyone know how to sort correctly?

Code:

Map<dynamic, dynamic> map = snapshot.data?.snapshot?.value;
    map.values.toList().sort((a, b) {
      return a['timestamp'].compareTo(b['timestamp']);
    // also not work return b['timestamp'].compareTo(a['timestamp']);
  });
like image 748
Daibaku Avatar asked Sep 04 '18 02:09

Daibaku


2 Answers

From the above code, it looks like you are not having a variable to hold the list.

 Map<dynamic, dynamic> map = {
    "one": {"timestamp": 1},
    "two": {"timestamp": 2}
  };
  List list = map.values.toList(); //variable which holds new list created from Map.
                                   //As it new list, any change in list will not have no impact on map.
  list.sort((a, b) {
    return b["timestamp"].compareTo(a["timestamp"]);
  }); // inplace sort
  print(list); // [{timestamp: 2}, {timestamp: 1}]

If you want key also in the result,

 var list = map.entries.toList();
 list.sort((a, b) => b.value["timestamp"].compareTo(a.value["timestamp"]));
 var list2 = list.map((a) => {a.key: a.value}).toList();
 print(list2); // [{two: {timestamp: 2}}, {one: {timestamp: 1}}]
like image 149
Dinesh Balasubramanian Avatar answered Sep 21 '22 16:09

Dinesh Balasubramanian


Unfortunately when you call snapshot.data?.snapshot?.value, the resulting Map doesn't have space for the order of the items anymore.

In most Firebase SDKs you can solve this by looping over the children of the snapshot in the value event listener. But in Flutter you will need to listen to onChildAdded events to maintain the value of the items in Flutter, at least until this issue is addressed: https://github.com/flutter/flutter/issues/20745.

From one of my own projects:

ref.orderByKey().equalTo("child1").onChildAdded.listen((event) {
  print(event.snapshot.key);
});
ref.child("child1").once().then((snapshot) {
  print("Done loading all data for child1");
});

This will first print the keys of all child nodes (in the requested order), and then "Done loading all data for child1".

like image 31
Frank van Puffelen Avatar answered Sep 22 '22 16:09

Frank van Puffelen