I am getting an empty array back from firestore. Specifically from the sub model "Coor" inside of "EventModel".
Data Model:
struct EventModel: Identifiable, Codable {
var id: String
var isLive: Bool
var coors: [Coor]
var eventCenterCoor: [Double]
var hostTitle: String
var eventName: String
var eventDescription: String
var isEventPrivate: Bool
var eventGuestsJoined: [String]
var eventEndDate: String
private enum CodingKeys: String, CodingKey {
case id
case isLive
case coors
case eventCenterCoor
case hostTitle
case eventName
case eventDescription
case isEventPrivate
case eventGuestsJoined
case eventEndDate
}
}
struct Coor: Identifiable, Codable {
var id = UUID()
var coorDoubles: [Double]
private enum CodingKeys: String, CodingKey {
case coorDoubles
}
}
Firestore request:
public func getEventData(completion: @escaping (_ eventModel: [EventModel]) -> Void) {
var eventRef: [EventModel] = []
self.isLoading = true
self.loadingMess = "Finding events.."
self.eventsDataCollection.whereField("isLive", isEqualTo: true)
.getDocuments { (document, error) in
if let document = document, error == nil {
for doc in document.documents {
let data = doc.data()
let id = data["id"] as? String ?? ""
let isLive = data["isLive"] as? Bool ?? false
let coors = data["coors"] as? [Coor] ?? []
let eventCenterCoor = data["eventCenterCoor"] as? [Double] ?? []
let hostTitle = data["hostTitle"] as? String ?? ""
let eventName = data["eventName"] as? String ?? ""
let eventDescription = data["eventDescription"] as? String ?? ""
let isEventPrivate = data["isEventPrivate"] as? Bool ?? false
let eventGuestsJoined = data["eventGuestsJoined"] as? [String] ?? []
let eventEndDate = data["eventEndDate"] as? String ?? ""
eventRef.append(EventModel(id: id, isLive: isLive, coors: coors, eventCenterCoor: eventCenterCoor, hostTitle: hostTitle, eventName: eventName, eventDescription: eventDescription, isEventPrivate: isEventPrivate, eventGuestsJoined: eventGuestsJoined, eventEndDate: eventEndDate))
}
completion(eventRef)
} else if error != nil {
print(error ?? "Error getting events where 'isLive' == true")
self.isLoading = false
}
}
}
Here is the firestore data:
Printing "coors" returns an empty array. The empty array is because this line:
let coors = data["coors"] as? [Coor] ?? []
is defaulting to the empty array. This must mean the data type of [Coor] is incorrect?
CodePudding user response:
You are decoding an array called coorsDouble with this line:
let coorsDouble = data["coorsDouble"] as? [Coor] ?? []
If you look at your data structure, each element is made up of this structure:
{ coolDouble: [Double] }
But, in your Coor model, you have this structure:
struct Coor: Identifiable, Codable {
var id = UUID()
var coor: [Double]
private enum CodingKeys: String, CodingKey {
case coor
}
}
In order to decode the Coor, you'd need its structure to match. So, change it to:
struct Coor: Identifiable, Codable {
var id = UUID()
var coorDouble: [Double]
private enum CodingKeys: String, CodingKey {
case coorDouble
}
}
Next, CodingKeys only take effect when using Codable. Right now, you're just trying to cast a dictionary value (of type Any) to Coor, which isn't going to work. In general, I'd say you should use Codable with your entire structure, but if you wanted to avoid it for some reason, you'd need to do this:
//replacing let coorsDouble = data["coorsDouble"] as? [Coor] ?? []
let coorsDoubleArray = data["coorsDouble"] as? [[String:Any]] ?? []
let coorsDouble = coorsDoubleArray.compactMap { item in
guard let doublesArray = item["coorDoubles"] as? [Double] else {
return nil
}
return Coor(coorDoubles: doublesArray)
}

