You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase匹配数据解码失败:JSON序列化后无法解析为FirestoreMatch

解码Firestore匹配数据时遇到类型不匹配错误

从Firebase获取匹配数据时,解码环节失败,相同逻辑在获取用户资料时可正常运行。

相关代码片段

fetchMatches函数

func fetchMatches(onCompletion: @escaping (Result<[MatchModel], DomainError>) -> ()){
    db.collection("matches").whereField("usersMatched", arrayContains: userId!).getDocuments(completion: {doc, err in
        guard let documentSnapshot = doc, err == nil else{
            onCompletion(.failure(.downloadError))
            return
        }
        var matchList: [MatchModel] = []
        var count = 0
        let maxCount = documentSnapshot.documents.count
        var hasFailed = false
        for document in documentSnapshot.documents{
            if hasFailed{ break }
            
            let decoder = JSONDecoder()
            var dict = document.data()

            for (key, value) in dict {
                                
                if let value = value as? Timestamp {
                    
                    let formatter = DateFormatter()
                    let newValue = value.dateValue()
                    formatter.dateStyle = .short
                    formatter.timeStyle = .none
                    dict[key] = formatter.string(from: newValue)
                   }
                 }
        // 后续解码逻辑省略
    })
}

处理后的字典内容

Dictionary
["timestamp": "10/22/22", "usersMatched": <__NSArrayM 0x600002c61680>(
6euZHDmI7PMDcCmft5MfxUW27jI3,
tbcB0ay0YEgZcY9UsZ00WjZ9h893
)
]

错误信息

typeMismatch(Swift.Double, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "timestamp", intValue: nil)], debugDescription: "Expected to decode Double but found a string/data instead.", underlyingError: nil))

FirestoreMatch结构体定义

struct FirestoreMatch: Codable{
    let usersMatched: [String]
    let timestamp: Date
}

问题原因与解决方案

问题根源

你手动将Firestore的Timestamp类型转换为了字符串格式(如"10/22/22"),但FirestoreMatch的timestamp字段是Date类型。JSONDecoder默认会尝试将数字类型的时间戳解码为Date,遇到字符串时就会抛出类型不匹配错误。

解决方案1:使用Firebase内置的Codable解析(推荐)

移除手动转换Timestamp为字符串的循环代码,直接用Firebase提供的data(as:)方法解析文档,它会自动处理Timestamp到Date的转换:

for document in documentSnapshot.documents{
    if hasFailed{ break }
    do {
        let match = try document.data(as: FirestoreMatch.self)
        matchList.append(match)
        // 后续处理逻辑
    } catch {
        hasFailed = true
        onCompletion(.failure(.downloadError))
    }
}

解决方案2:配置JSONDecoder解析自定义日期字符串

如果坚持要保留手动转换字符串的逻辑,需要给JSONDecoder设置对应的日期解析器,让它能识别你生成的字符串格式:

let decoder = JSONDecoder()
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .none
dateFormatter.locale = Locale(identifier: "en_US_POSIX") // 确保解析格式与生成时一致
decoder.dateDecodingStrategy = .formatted(dateFormatter)

// 之后再用该decoder解码数据
do {
    let data = try JSONSerialization.data(withJSONObject: dict)
    let match = try decoder.decode(FirestoreMatch.self, from: data)
    matchList.append(match)
} catch {
    hasFailed = true
    onCompletion(.failure(.downloadError))
}

内容的提问来源于stack exchange,提问作者Anthony contreras

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 03:20:31