Firestore生成连续文档ID时跨表计数错误、删除后计数异常问题
问题根因
你遇到的两个序号异常问题核心由以下3个错误导致:
- 异步回调时序错误:Firestore的
getDocuments是异步网络请求,你当前把complete()回调写在了请求逻辑的外部,会导致还没从云端拿到当前Table的饮品集合数据,就已经提前执行了保存逻辑,用的是上一次缓存的drinkCount值,所有跨操作场景都会出现序号异常。 - 全局计数变量污染:
drinkCount是ViewModel的全局属性,不同Table的序号生成操作共用同一个变量,上一个Table计算得到的序号没有被正确重置就会用到下一个Table的生成逻辑中。 - 计数逻辑冗余:不需要循环遍历所有文档累加计数,直接读取
querySnapshot.documents.count即可拿到当前集合的文档总数。
修复方案
修改核心逻辑如下:
- 将
complete()回调移动到getDocuments的异步回调内部,确保拿到最新的集合数据后再执行后续保存操作 - 调整闭包参数直接返回计算好的序号,取消全局共享的
drinkCount变量,避免不同Table的操作互相干扰 - 简化计数逻辑,直接用集合文档总数计算下一个序号
修复后完整代码:
class OrderViewModel : ObservableObject { func saveDrinks(table : String, drinkCount: Int) { var drinks : [[String : Any]] = [] var drinkextra : [[String: Any]] = [] for j in cartDrinks { for i in j.extra { drinkextra.append(["extra": i.extra,"price": i.price]) drinks.append([ "Name":j.name, "Unit":j.unit , "Price":j.price, "Extra": drinkextra ]) drinkextra.removeAll() } } db.collection("Active Table").document("Table \(table)").collection("Drinks").document("Drink \(drinkCount)").setData(["Drinks": drinks]){ error in if let error = error { print(error.localizedDescription) } } } func generateDrinkTitle(table: String,complete:@escaping(_ drinkCount: Int) -> Void) { let docRef = db.collection("Active Table").document(table).collection("Drinks") docRef.getDocuments { querySnapshot, error in if let err = error { print("Error in getting: \(err.localizedDescription)") complete(1) // 出错时默认从1开始 } else { let docCount = querySnapshot?.documents.count ?? 0 complete(docCount + 1) } } } func FireUpload(table: String){ db.collection("Active Table").document("Table \(table)").setData(["Time" : Timestamp(date: Date())]) { error in if let error = error { print(error.localizedDescription) return } } if !mealDeal.mainCourse.isEmpty { self.SaveMealDeal(table: table) } if !cartDrinks.isEmpty { generateDrinkTitle(table: "Table \(table)") { [weak self] drinkCount in guard let self = self else { return } self.saveDrinks(table: table, drinkCount: drinkCount) } } if !cartexpress.isEmpty { self.SaveAlacarte(table: table) } } }
内容的提问来源于stack exchange,提问作者Liangn1an
相关产品推荐
相关产品推荐

