Firebase-SwiftUI中无法将数据映射到@Published变量
问题排查与解决方案
1. 即时打印的时机问题
你当前的print(self.cars)写在DispatchQueue.main.async闭包外部,而闭包内的数组赋值是异步执行的,此时打印的还是未更新的空数组,并非赋值后的结果。把打印代码移到闭包内部即可看到最新数据:
DispatchQueue.main.async { self.cars = documents.map { ... } print(self.cars) // 移至此处查看赋值后的数组 }
2. 替换手动映射为Codable解码(更可靠)
你已经为Cars实现了Codable协议,没必要手动逐个提取字段,直接用Firestore自带的解码方法,避免手动映射的疏漏:
修改fetchData中的映射逻辑:
DispatchQueue.main.async { self.cars = documents.compactMap { doc in do { let car = try doc.data(as: Cars.self) return car } catch { print("解码失败:\(error)") return nil } } print(self.cars) }
注意:确保Firestore中的字段类型与Cars定义完全匹配,比如若id_cars在Firestore中是数字类型,而你定义的carID是String,解码会失败,需统一类型(要么把carID改为Int,要么在Firestore中存字符串)。
3. 检查View中ViewModel的使用方式
确认在View中用@StateObject(iOS 14+)或@ObservedObject持有ViewModel,并正确监听cars的变化:
struct CarsView: View { @StateObject var viewModel = AssetsViewModel() var body: some View { List(viewModel.cars) { car in Text(car.brand ?? "Unknown") } .onAppear { viewModel.fetchData() } } }
4. 再次验证Firestore字段名匹配度
再次核对Firestore中的字段名与CodingKeys的一致性,包括空格、大小写(比如Driver train的空格、HorsePower的大小写必须完全对应)。
内容的提问来源于stack exchange,提问作者SinaBagheri
相关产品推荐
相关产品推荐

