Firebase函数返回Timestamp在Swift中解码失败的解决方法咨询
解决方案
方式一:修改Firebase函数,转换Timestamp格式返回
Firebase Functions返回的Timestamp会被序列化为带_seconds和_nanoseconds键的对象,但Firestore.Decoder默认期望不带下划线的seconds和nanoseconds(直接读取Firestore文档时的格式)。可以在函数里把Timestamp转成更易兼容的格式:
- 转成ISO 8601字符串
[{ startTime: firestore.Timestamp.fromDate(randomDate).toDate().toISOString(), duration: 45 }]
Swift端无需额外修改,Firestore.Decoder或默认的JSONDecoder都能直接将ISO字符串解码为Date类型。
- 转成时间戳数值(秒/毫秒)
[{ startTime: firestore.Timestamp.fromDate(randomDate).seconds, // 秒级时间戳 // 也可以用毫秒级:startTime: firestore.Timestamp.fromDate(randomDate).toDate().getTime() duration: 45 }]
Swift端需调整解码逻辑,比如自定义Date的解码过程:
struct AvailabilityTimeSlot: Codable { let startTime: Date let duration: Int enum CodingKeys: String, CodingKey { case startTime, duration } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let timestamp = try container.decode(TimeInterval.self, forKey: .startTime) startTime = Date(timeIntervalSince1970: timestamp) duration = try container.decode(Int.self, forKey: .duration) } }
方式二:在Swift端自定义解码适配Functions返回格式
如果不想修改Firebase函数,可以自定义解码逻辑,适配带下划线的键:
// 定义适配Functions Timestamp的结构体 struct FunctionsTimestamp: Codable { let seconds: Int64 let nanoseconds: Int32 enum CodingKeys: String, CodingKey { case seconds = "_seconds" case nanoseconds = "_nanoseconds" } var date: Date { Date(timeIntervalSince1970: TimeInterval(seconds) + TimeInterval(nanoseconds)/1e9) } } // 修改AvailabilityTimeSlot的解码逻辑 struct AvailabilityTimeSlot: Codable { let startTime: Date let duration: Int enum CodingKeys: String, CodingKey { case startTime, duration } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let ts = try container.decode(FunctionsTimestamp.self, forKey: .startTime) startTime = ts.date duration = try container.decode(Int.self, forKey: .duration) } }
解码时改用默认的JSONDecoder即可:
return try JSONDecoder().decode([AvailabilityTimeSlot].self, from: result.data)
问题根源
直接从Firestore读取文档时,Firestore SDK会自动将存储的Timestamp映射为Swift的Date或Timestamp类型,Firestore.Decoder专门适配这种不带下划线的键格式。但Firebase Functions返回的是JSON序列化后的结果,Timestamp会被序列化为带下划线前缀的键,导致Firestore.Decoder无法识别。
内容的提问来源于stack exchange,提问作者aryaxt
相关产品推荐
相关产品推荐

