Bruno
Bruno

Reputation: 1032

Firebase timestamp decode

I have the following object:

struct CustomModel: Codable {
    var id: String?
    var creationTime: Timestamp? <-----
    var providerData: [ProviderData]?
    var uid: String?

    enum CodingKeys: String, CodingKey {
        case id
        case creationTime
        case providerData
        case uid
    }
}

Decoding it:

JSONDecoder().decode(CustomModel.self, from: jsonData)

I'm getting the following error for trying to Decode the Firebase Timestamp:

could not parse json keyNotFound(TimestampKeys(stringValue: "seconds", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "creationTime", intValue: nil)], debugDescription: "No value associated with key TimestampKeys(stringValue: "seconds", intValue: nil) ("seconds").", underlyingError: nil))

I'm using Firebase Functions to interact with Firebase, and with that I need to decode this object, the problem is that I have no idea how to handle the creationTime firebase timestamp. I don't wanna use CodableFirestore library since its outdated. Any suggestions?

Upvotes: 1

Views: 584

Answers (2)

Ihor Chernysh
Ihor Chernysh

Reputation: 496

You can just create the model:

struct CustomModel: Codable {
    var id: String?
    var creationTime: Date?

    enum CodingKeys: String, CodingKey {
        case id
        case creationTime
    }
}

And the init for the model:

init(from decoder: Decoder) throws {
  let values = try decoder.container(keyedBy: CodingKeys.self)
  self.type = try values.decode(String.self, forKey: .id)
  let dateString = try values.decode(String, forKey: .createdAt)
  self.creationTime = dateString.iso8601withFractionalSeconds
}

See the formatting String to date by calling 'iso8601withFractionalSeconds' here How can I parse / create a date time stamp formatted with fractional seconds UTC timezone (ISO 8601, RFC 3339) in Swift?

All other values you can also decode by following Swift decoding requirements.

Upvotes: 1

slushy
slushy

Reputation: 12385

The problem here is that Timestamp is not a supported type of the Codable protocol. Remember that Timestamp is a Firestore custom type, not a native Swift type. Date, however, is a native Swift type and one that is supported by Codable, and it's easily convertible between Timestamp.

let date = timestamp.dateValue()
let timestanmp = Timestamp(date: date)

Upvotes: 1

Related Questions