Timestamp Handling
yangricardo opened this issue · 5 comments
Hi am having this issue with CodableFirebase decoding
I have some Codable fields that represents Dates, already tried Date Swift and Firebase Timestamp, used the extension Timestamp: TimestampType {}
in my code and still receiving this error:
Thread 1: Fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.typeMismatch(Swift.Double, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "dataNascimento", intValue: nil)], debugDescription: "Expected to decode Double but found FIRTimestamp instead.", underlyingError: nil))
At some point of time this fields needs to be nil
, and it works, but only when i fetch data from Firestore after update this field i get this error.
Hi! Thanks for posting your question! Could you please share the code with your struct that conforms to Codable
?
Hi, thanks to answer!
An example is this:
class HabilitacaoBeneficiario: Codable {
var nomeCompleto : String?
var cpf : String?
var dataNascimento : Timestamp?
var grauParentesco : String?
var registroGeral : String?
var orgãoEmissor : String?
var dataExpedicao : Timestamp?
var estadoCivil : CivilStatus?
var numeroFilhos : Int?
var faixaRenda : Income?
var ppe : Bool?
var residenteBrasil : Bool?
var fiscalExterior : Bool?
var profissao : String?
var telefone : String?
var celular : String?
var endereco : String?
var numero : String?
var complemento : String?
var bairro : String?
var cidade : String?
var estado : String?
var cep : String?
var email : String?
var formaPagamento : PaymentWay?
var banco : BrazilBanks?
var agencia : String?
var contaCorrent : String?
var receberEmail: Bool?
init() {
self.nomeCompleto = nil
self.cpf = nil
self.dataNascimento = nil
self.grauParentesco = nil
self.registroGeral = nil
self.orgãoEmissor = nil
self.dataExpedicao = nil
self.estadoCivil = nil
self.numeroFilhos = nil
self.faixaRenda = nil
self.ppe = nil
self.residenteBrasil = nil
self.fiscalExterior = nil
self.profissao = nil
self.telefone = nil
self.celular = nil
self.endereco = nil
self.numero = nil
self.complemento = nil
self.bairro = nil
self.cidade = nil
self.estado = nil
self.cep = nil
self.email = nil
self.formaPagamento = nil
self.banco = nil
self.agencia = nil
self.contaCorrent = nil
self.receberEmail = nil
}
}
I have DAO that manages the document creation easily, but also this Listener that is refreshed at some point
func listenHabilitacao() {
self.habilitacaoRef = DAOFirebase.shared.getUserDocumentRef()?.collection("beneficiario").document("habilitacao")
self.habilitacaoListener = self.habilitacaoRef?.addSnapshotListener({ (habilitacaoSnapshot, error) in
guard let habilitacao = habilitacaoSnapshot, habilitacao.exists else {
return
}
if !(habilitacao.data()?.isEmpty)! {
let habilitacaoDecoded : HabilitacaoBeneficiario = try!FirebaseDecoder().decode(HabilitacaoBeneficiario.self, from: habilitacao.data() ?? [:])
self.form = habilitacaoDecoded
}
})
}
And this in other view controller
func listenHabilitacao() {
self.habilitacaoRef = DAOFirebase.shared.getUserDocumentRef()?.collection("beneficiario").document("habilitacao")
self.habilitacaoListener = self.habilitacaoRef?.addSnapshotListener({ (habilitacaoSnapshot, error) in
guard let habilitacao = habilitacaoSnapshot, habilitacao.exists else {
return
}
if !(habilitacao.data()?.isEmpty)! {
let habilitacaoDecoded : HabilitacaoBeneficiario = try!FirebaseDecoder().decode(HabilitacaoBeneficiario.self, from: habilitacao.data() ?? [:])
self.form = habilitacaoDecoded
}
})
}
that are updated by this method ( with a little modifications after first issue glance, but still with same issues )
func saveHabilitacaoBeneficiario(habilitacao : HabilitacaoBeneficiario) -> (message :String, firestoreError:FirestoreErrorCode?){
var errorCode : (String, FirestoreErrorCode?) = ("",nil)
// codifica habilitacao para o firestore
var habilitacaoData : [String : Any] = try! FirebaseEncoder().encode(habilitacao) as! [String : Any]
habilitacaoData.updateValue(habilitacao.dataExpedicao as Any, forKey: "dataExpedicao")
habilitacaoData.updateValue(habilitacao.dataNascimento as Any, forKey: "dataNascimento")
// adiciona o documento
let habilitacaoCollection = self.addUserSubCollectionDocument(forUser: (self.user?.uid)!, subcollectionId: "beneficiario", subDocumentId: "habilitacao", data: habilitacaoData)
errorCode = (habilitacaoCollection.error.message,habilitacaoCollection.error.firestoreError)
// obtem colecao beneficiario para atualizar lista de requerimentos
let requirementsRef : DocumentReference? = getUserDocumentRef()?.collection("beneficiario").document("requerimentos")
requirementsRef?.getDocument(completion: { (document, error) in
if error != nil {
errorCode = self.handleFirestoreError(error: error!)
} else if let document = document {
// obtem lista de requerimentos
var requirementsData : [String : Any] = document.data()!
let dataCriacao : Any = requirementsData["dataCriacao"] ?? Timestamp() as Any
requirementsData.updateValue(dataCriacao, forKey: "dataCriacao")
requirementsData.updateValue(Timestamp(), forKey: "dataAtualizacao")
requirementsData.updateValue(true, forKey: "completed")
document.reference.setData(requirementsData, merge: true){
err in
if let error = err {
errorCode = self.handleFirestoreError(error: error)
}
}
}
})
return errorCode
}
You are using FirebaseDecoder, you need to use FirestoreDecoder and Encoder instead
Can't believe it hahaha
Thanks, too similar names!
Funny but I've encountered the same issue after 2 years. Hahaha