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

Firestore生成连续文档ID时跨表计数错误、删除后计数异常问题

问题根因

你遇到的两个序号异常问题核心由以下3个错误导致:

  • 异步回调时序错误:Firestore的getDocuments是异步网络请求,你当前把complete()回调写在了请求逻辑的外部,会导致还没从云端拿到当前Table的饮品集合数据,就已经提前执行了保存逻辑,用的是上一次缓存的drinkCount值,所有跨操作场景都会出现序号异常。
  • 全局计数变量污染:drinkCount是ViewModel的全局属性,不同Table的序号生成操作共用同一个变量,上一个Table计算得到的序号没有被正确重置就会用到下一个Table的生成逻辑中。
  • 计数逻辑冗余:不需要循环遍历所有文档累加计数,直接读取querySnapshot.documents.count即可拿到当前集合的文档总数。
修复方案

修改核心逻辑如下:

  1. 将complete()回调移动到getDocuments的异步回调内部,确保拿到最新的集合数据后再执行后续保存操作
  2. 调整闭包参数直接返回计算好的序号,取消全局共享的drinkCount变量,避免不同Table的操作互相干扰
  3. 简化计数逻辑,直接用集合文档总数计算下一个序号

修复后完整代码:

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 18:27:03