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

Firebase函数返回Timestamp在Swift中解码失败的解决方法咨询

解决方案

方式一:修改Firebase函数,转换Timestamp格式返回

Firebase Functions返回的Timestamp会被序列化为带_seconds和_nanoseconds键的对象,但Firestore.Decoder默认期望不带下划线的seconds和nanoseconds(直接读取Firestore文档时的格式)。可以在函数里把Timestamp转成更易兼容的格式:

  1. 转成ISO 8601字符串
[{
    startTime: firestore.Timestamp.fromDate(randomDate).toDate().toISOString(),
    duration: 45 
}]

Swift端无需额外修改,Firestore.Decoder或默认的JSONDecoder都能直接将ISO字符串解码为Date类型。

  1. 转成时间戳数值(秒/毫秒)
[{
    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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 04:35:51