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

如何在Firestore中用Where条件查询指定枚举值的文档

解决Firestore中Codable枚举的查询问题

问题根源

你定义的无关联值Codable枚举,Swift默认会将其编码为仅包含当前case名称作为键、值为空的对象(比如notOpen会被编码为{"notOpen": ""}),这种嵌套存储结构导致你之前的查询方式无法正确匹配。


临时解决方案(针对已存储的数据)

如果不想修改现有数据结构,可以将目标枚举值编码为对应字典,再用该字典作为查询条件:

let targetStatus = washingPowderState.notOpen
do {
    // 将枚举编码为Firestore存储的字典格式
    let encodedData = try JSONEncoder().encode(targetStatus)
    guard let statusDict = try JSONSerialization.jsonObject(with: encodedData, options: []) as? [String: Any] else {
        print("编码枚举失败")
        return
    }
    
    db.collection(K.NoSQLCollections.washingPowder)
        .whereField("roles.\(uid)", isEqualTo: K.Roles.owner)
        .whereField("status", isEqualTo: statusDict)
        .getDocuments { querySnapshot, err in
            // 处理查询结果
        }
} catch {
    print("编码枚举出错:\(error)")
}

最优解决方案(修改枚举编码逻辑)

更推荐修改枚举的Codable实现,让它直接存储为字符串,这样查询更简洁直观,也符合Firestore的常用数据格式:

方法1:使用String原始值枚举

让枚举继承String类型,Codable会自动将其编码为对应的字符串:

enum WashingPowderState: String, Codable {
    case notOpen, open, used
}

此时Firestore中status字段的值会是"notOpen"/"open"/"used",查询代码可以简化为:

db.collection(K.NoSQLCollections.washingPowder)
    .whereField("roles.\(uid)", isEqualTo: K.Roles.owner)
    .whereField("status", isEqualTo: WashingPowderState.notOpen.rawValue)
    .getDocuments { querySnapshot, err in
        // 处理查询结果
    }

方法2:自定义Codable实现

如果不想使用原始值,可以手动实现编码解码逻辑,强制将枚举转为字符串存储:

enum WashingPowderState: Codable {
    case notOpen, open, used
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch self {
        case .notOpen: try container.encode("notOpen")
        case .open: try container.encode("open")
        case .used: try container.encode("used")
        }
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        let rawValue = try container.decode(String.self)
        switch rawValue {
        case "notOpen": self = .notOpen
        case "open": self = .open
        case "used": self = .used
        default:
            throw DecodingError.dataCorruptedError(in: container, debugDescription: "无效的洗涤粉状态值:\(rawValue)")
        }
    }
}

查询方式和方法1一致,直接匹配对应的字符串值即可。


内容的提问来源于stack exchange,提问作者Max Mikkelsen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 00:10:55