0

I am using a Firebase query to return orders within a date range. The date is saved as a string. However, this is returning incorrect information.

    let startDate = "\(selectedDateStart.startOfMonth())"
    let endDate = "\(selectedDateEnd.endOfMonth())"
    let query = DATABASE.mainOrder.child(orderLocation).queryOrdered(byChild: "orderDate").queryStarting(atValue: startDate).queryEnding(atValue: endDate+"\u{f8ff}")
    query.observeSingleEvent(of: .value, with:{ (snapshot) in
        if let tallies = snapshot.value as? [String:[String:Any]] {
            self.allFilteredOrdersMonth = self.allFilteredOrdersMonth.merging(tallies) { (_, new) in new }
            for items in tallies.keys {
                print("Month Start Date Search: \(startDate), End Date Search: \(endDate), Order #: \(items), Order # Date Created: \(tallies[items]!["orderDate"]!)")
            }
        }
        completionHandler()
    })

I have attached one of the results below from a query.

startDate = 01/01/2022

endDate = 01/31/2022

Returned Order #: *****

Returned Order # Date Created: 01/19/2021

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
Will
  • 11
  • 2
  • If you save the date as a string it will be sorted and compared as a string and not a date and furthermore with that particular format it will never work. You could get away with using a string if you used a format like yyyy-MM-dd, i.e 2022-01-01 because then 2021 would be sorted before 2022. Now 01/19 is sorted between 01/01 and 01/31 – Joakim Danielson Aug 20 '21 at 13:27
  • The issue is Firebase does not allow storing date – Will Aug 20 '21 at 13:29
  • Read my whole comment – Joakim Danielson Aug 20 '21 at 13:30
  • In lexicographical/alphabetical order (which is how strings are sorted) the value "01/01/2022" comes before "01/19/2021", because "01/01" comes before "01/19". The solution is (as Joakim and Alex have said) to store the data in either a string format that allows ordering, or as a timestamp number. See https://stackoverflow.com/questions/52728669/querying-by-range-in-firebase/52732340#52732340, https://stackoverflow.com/a/38226376/209103 and more from https://stackoverflow.com/search?q=%5Bfirebase-realtime-database%5D+lexicographical+number – Frank van Puffelen Aug 20 '21 at 14:35

1 Answers1

1

If you store dates as strings in the following format:

01/01/2022

And you try to perform an order, please note that strings are ordered lexicographically

If you want to get the correct order, you should store the dates as timestamps.

According to your comment:

The issue is Firebase does not allow storing date

It actually does:

let timestamps = ["startDate": ServerValue.timestamp(), "endDate": ServerValue.timestamp()] as [String : Any]
ref.updateChildValues(timestamps) { (err, ref) in
    if let err = err {
        print("failed to upload user data", err)
        return
    }

}
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • So I can just do this? db.child("orderDate").setValue(ServerValue.timestamp()) – Will Aug 20 '21 at 13:51
  • You should use a data structure that allows you to perform the update. Have you tried the solution in my answer? Does it work? – Alex Mamo Aug 20 '21 at 14:03