Home > front end >  How to create index for conditional selected sort fields query in Firebase?
How to create index for conditional selected sort fields query in Firebase?

Time:12-16

For example, I have data structure like this

// Document 1
{
  "type":"Child",
  "createdDate":"01/01/2020",
  "birthDate":"08/01/2002",
}

// Document 2
{
  "type":"Adult",
  "createdDate":"05/01/2020",
  "birthDate":"08/01/1990",
}

I want to query sorted documents with this sort function in Flutter

(a, b) {
  DateTime da = a.type == "Child" ? a.createdDate: a.birthDate;
  DateTime db = a.type == "Child" ? a.createdDate: a.birthDate;
  return da.compareTo(db);
}

In short if it a Child, select createdDate to compare, else select birthDate to compare.

Can I do this in firebase?

I can't query all data then sort in frontend because I want to use FirestoreListView

CodePudding user response:

The only way I see, is to create a helper field in the DB which shows the createdDate for children and the birthDate for adults. Then you can sort for this field

CodePudding user response:

I have not your Class model so I run the logic on the list but you can do this on model too.

First you can't sort a list with two different sort, I recommend first split those into two group as child and adult, then sort theme then merge them together, for grouping I used collection package, let say this is your list:

List<Map<String, String>> dataList = [
    {
      "type": "Child",
      "createdDate": "08/01/2020",
      "birthDate": "09/01/2002",
    },
    {
      "type": "Child",
      "createdDate": "01/01/2020",
      "birthDate": "08/01/2002",
    },
    {
      "type": "Adult",
      "createdDate": "05/01/2020",
      "birthDate": "10/01/1990",
    },
    {
      "type": "Adult",
      "createdDate": "05/01/2020",
      "birthDate": "08/01/1990",
    },
  ];

you can sort them like this:

var grouped = groupBy(dataList, (Map value) => value['type']);

var result = grouped.entries
    .map((e) {
      e.value.sort(
        (a, b) => e.key == "Child"
            ? a["createdDate"]
                .toString()
                .compareTo(b["createdDate"].toString())
            : a["birthDate"]
                .toString()
                .compareTo(b["birthDate"].toString()),
      );
      return e.value;
    })
    .toList()
    .expand((element) => element)
    .toList();

result:

[
   {type: Child, createdDate: 01/01/2020, birthDate: 08/01/2002},
   {type: Child, createdDate: 08/01/2020, birthDate: 09/01/2002},
   {type: Adult, createdDate: 05/01/2020, birthDate: 08/01/1990},
   {type: Adult, createdDate: 05/01/2020, birthDate: 10/01/1990}
]
  • Related