Firestore异步setData方法无法抛出服务端错误该如何处理
问题原因
Firestore的setData(from:)有两个行为完全不同的重载:
- 无回调版本:为乐观写入设计,调用后立即在本地缓存生效,不等待服务端响应,仅会抛出本地编码错误、无效引用等本地侧问题,不会返回服务端权限错误、网络错误等服务端响应的错误。
- 带完成回调版本:会等待服务端返回写入结果,回调入参的可选
error就是服务端/网络层返回的写入异常。
回调属于逃逸闭包,执行时外层函数的调用栈已经退出,直接在回调闭包内throw无法被外层async throws上下文捕获,必须通过Swift并发提供的续体(continuation)桥接才能把错误向外抛出。
实现代码
使用withCheckedThrowingContinuation将回调式API桥接到异步抛出上下文,修改后的方法实现如下:
import Foundation import FirebaseFirestore class DatabaseProvider: ObservableObject { static let shared = DatabaseProvider() private var db = Firestore.firestore() private init() {} } // MARK: 文档增删改查相关方法 extension DatabaseProvider { /// 通用数据写入方法 /// - Parameters: /// - collection: 数据要写入的集合 /// - documentId: 可选自定义文档ID,传nil时自动生成ID /// - data: 要写入的可序列化数据对象 func addDocument<T: Codable>( to collection: Collections, documentId: String? = nil, with data: T ) async throws { let collectionReference = db.collection(collection.name) let documentReference: DocumentReference if let documentId = documentId { documentReference = collectionReference.document(documentId) } else { documentReference = collectionReference.document() } // 桥接回调API到async/throws上下文,等待服务端响应后再返回/抛出错误 try await withCheckedThrowingContinuation { continuation in documentReference.setData(from: data.self) { error in if let error = error { continuation.resume(throwing: error) } else { continuation.resume() } } } } }
注意:实现时删除原来无回调的
setData调用,否则会触发重复写入。
内容的提问来源于stack exchange,提问作者cs4alhaider
相关产品推荐
相关产品推荐

