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
相关产品推荐
相关产品推荐

