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

FirebaseFunctions iOS SDK传入Data实例触发不支持类型错误求解决

解决方案

Firebase可调用函数的call(_:completion:)方法仅支持JSON兼容的基础类型(字符串、数字、布尔值、数组、字典及它们的嵌套组合),Data实例和自定义结构体不在默认支持范围内,以下是除手动构造普通字典外的可行方案:


1. 将Data转换为Base64字符串传递

把二进制Data编码为Base64字符串(JSON兼容类型),Firebase可正常序列化该类型,云函数端再解码还原即可:

override func viewDidLoad() {
    super.viewDidLoad()
    
    let encoder = JSONEncoder()
    let item = A(i: "string")
    guard let encodedItem = try? encoder.encode(item) else { return }
    // 将Data转为Base64字符串
    let base64Item = encodedItem.base64EncodedString()
    
    functions.httpsCallable("foo").call([
        "item": base64Item
    ]) { result, error in
        // 处理回调结果
    }
}

云函数端示例(Node.js):

exports.foo = functions.https.onCall((data, context) => {
  const itemBuffer = Buffer.from(data.item, 'base64');
  // 后续处理还原后的数据
});

2. 自动将Codable结构体转为JSON字典

借助JSONSerialization把结构体的二进制编码数据转成Firebase支持的[String: Any]字典,无需手动映射键值对:

override func viewDidLoad() {
    super.viewDidLoad()
    
    let encoder = JSONEncoder()
    let item = A(i: "string")
    guard let encodedItem = try? encoder.encode(item),
          let itemDict = try? JSONSerialization.jsonObject(with: encodedItem) as? [String: Any] else { return }
    
    functions.httpsCallable("foo").call(itemDict) { result, error in
        // 处理回调结果
    }
}

3. 扩展Firebase Functions支持Codable类型

通过扩展Functions类,封装自动转换逻辑,让你可以直接传递Codable实例,无需每次手动处理:

import FirebaseFunctions

extension Functions {
    func httpsCallable<T: Codable>(_ name: String, callWith model: T, completion: @escaping (HTTPSCallableResult?, Error?) -> Void) {
        do {
            let jsonData = try JSONEncoder().encode(model)
            guard let params = try JSONSerialization.jsonObject(with: jsonData) as? [String: Any] else {
                let error = NSError(domain: "FunctionError", code: -1, userInfo: [NSLocalizedDescriptionKey: "无法将模型转换为字典"])
                completion(nil, error)
                return
            }
            self.httpsCallable(name).call(params, completion: completion)
        } catch {
            completion(nil, error)
        }
    }
}

使用方式简化为:

override func viewDidLoad() {
    super.viewDidLoad()
    
    let item = A(i: "string")
    functions.httpsCallable("foo", callWith: item) { result, error in
        // 处理回调结果
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 13:58:29