Failed to get the 'some' field from optional

Viewed 2479

astoundingly, typing this error into the Stack Overflow search returns no results that actually mention this error 0.0

So I have an Event object in my Swift IOS App which is saved as a document on Firestore that looks like this

enter image description here

The start and end fields are Timestamps.

Over on xcode when the Event collection is queried, the results are decoded into Events with this initialiser

init(document: DocumentSnapshot) {
       self.id = document.documentID
       let d = document.data()
       self.title = d!["title"] as? String
       
       let stamp = d!["start"] as? Timestamp
       let estamp = d!["end"] as? Timestamp
       
       self.start = stamp?.dateValue()
       self.end = estamp?.dateValue()
       /* 
          There is a breakpoint here!
       */
       self.creator = d!["user"] as? String
       
       self.isAllDay = (d!["isAllDay"] as? Bool)!
       
       self.isPrivate = d!["isPrivate"] as! Bool
       
       self.count = (d!["count"] as? String)!
       
       self.date = d?["day"] as? String
       self.month = d?["month"] as? String
       self.year = d?["year"] as? String
       
       self.bridgesDays = doesEventBridgeDays()
       //MARK: re-implement these functions
       
       isInvitee()
       
   }

I've just swapped this over from using Strings to Timestamps and i now have unexpectedly found nil errors for the start and end fields on the app.

a breakpoint shows me this:

enter image description here

As you can see, the start and end fields now say Failed to get the 'some' field from optional start/end (start and end are now both Date objects)

I either don't understand what i'm reading online, or there are no questions/blog posts etc about this on the internet so

what does this mean?

and how do I fix it?

happy to answer any further questions to help resolve this issue :)

Thanks :)

Extra information*

enter image description here

1 Answers

This is failing because your Event object in code is trying to store your 'start' and 'end' properties as a Date? but you're retrieving them from Firebase Firestore as a Timestamp.

You'll need to do an intermediate step to unwrap the values and then get the date object.

if let end = data["end"] as? Timestamp {
    self.end = end.dateValue()
}

Also, you should really be unwrapping the document.data() safely to avoid using the d! and risking a crash.

if let data = document.data(){
    // extract values
}

Finally, it may be worth reading the document on sending / retrieving custom objects with Firestore. It makes everything a lot easier.

Firestore.firestore().collection("Event").document(id).getDocument { (document, error) in
    if error != nil {
        print(error?.localizedDescription as Any)
    }
    guard let document = document else {
        // failed to unwrap document
        return
    }
    if document.exists {
        let result = Result {
            try document.data(as: Event.self)
        }
        switch result {
        case .success(let event):
            if let event = event {
                // do something with Event object
            } else {
                // failed to unwrap Event
            }
        case .failure:
            // failed to form Event
        }
    } else {
        // document doesn't exist
    }
}
Related