Search code examples
swiftsortingtableview

Swift Sorting Out Data From Firebase via Timestamp


Edit: Added screenshot of my example.

I have a firebase database where users upload information, as well as a date and time. I have successfully retrieved all this data, however I did want to ask a question regards to sorting information. Currently, my tableview which shows this data just shows the order in which users uploaded this information. I have played around with 'sort' command which successfully sorts out ascending or descending data by users.

However, I would like to sort out data based on the time users have chosen not based on who posted it first. Below is an example as well as my code. If someone can point out any improvements, that would be great!

Input for example: User A posts first at a time of 9 AM. User B posts second at a time of 10 AM. User C posts third at a time of 6 AM.

Sort by code: User A (9AM), User B (10AM), User C (6AM) OR User C (6AM), User B (10AM), User A (9AM)

What I Would Like: User C (6AM), User A (9AM), User B (10AM)

Code

func fetchData(for date: String) {
    
    guard let userId = Auth.auth().currentUser?.uid else { return }

    let journalRef = Database.database().reference().child("\(userId)/Events")

    journalRef.removeAllObservers()
        self.databaseRef = journalRef.child(date)
        self.databaseRef.observe(.value, with: {(snapshot) in
        self.events.removeAll()
        if snapshot.childrenCount>0 {
            for eventsFirebase in snapshot.children.allObjects as! [DataSnapshot] {
                if let eventsObject = eventsFirebase.value as? [String: AnyObject],
                   let eventTitle = eventsObject["eventTitle"] as? String,
                   let eventDay = workoutsObject["eventDay"] as? String,
                   let eventTiming = workoutsObject["eventTiming"] as? String {
                   let eventInDepth = EventInformation(id: eventInDepth.key, eventDay: eventDay, eventTiming: eventTiming, eventTitle: eventTitle)
                   self.events.append(eventInDepth)
 


                   self.events.sort(by: {$0.eventTiming > $1.eventTiming}) // this is it
                }
            }
        }
        self.eventsList.reloadData()
    })
}

I have tried the sort by code which sorts the time in which users have actually uploaded their data however i want to sort by the time they have chosen - 'eventTiming'.

Below is a screenshot to visualise what I mean. I would like it to be in a chronological time order, not in a chronological order from when it was uploaded. So in the below example, the order should be 6:00 AM, 6:30 AM and 7:00 AM.

Example


Solution

  • It looks like your “eventTiming” is a date/time string, not a numeric date or time. That is going to mess you up, since those will be sorted by string sorting rules, not date/time sorting rules.

    You’d be better off saving dates/times as numeric offsets from the UNIX epoch date. (Number of seconds/milliseconds since Midnight GMT on January 1, 1970.) Sort them by comparing numbers.

    There are also date string formats that work for string date sorting (4 digit year, followed by 2 digit month with leading zeros, followed by 2 digit day with leading zeros, followed by 24 hour time with leading zeros for the hours, minutes, and seconds.)

    Failing that, add a lazy property eventTimingDate to each struct that uses a static DateFormatter to convert your date string to a Date object. (By making it a lazy property you’ll only do the date string to date conversion once per object.)