我见过很多类似的问题,但似乎还没有一个可以为我的问题版本提供解决方案。
简单地说,当在 Firestore 中创建新数据后,由于向 Firebase Firestore 发出 get 请求而更新已发布属性中的数据时,ForEach 列表视图不会更新(或者更准确地说,我怀疑更新得太快)。我很抓狂,因为另一个几乎相同的列表也连接到 Firestore,可以按预期工作 - 我知道的唯一区别是我的数据库服务功能的依赖注入。
详情:
型号
struct VenueCollection: Codable, Identifiable {
@DocumentID var id: String?
var name: String
var description: String?
var venues: [String: Date] // Where string is venue ID and Date is date added to collection
}
视图模型
class AuthViewModel:NSObject, ObservableObject, ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding {
@Published var collections: [VenueCollection] = []
func getUserCollections() {
guard let userID = Auth.auth().currentUser?.uid else { return }
databaseService.getUserCollections(userID: userID) { [weak self] result in
DispatchQueue.main.async {
switch result {
case .success(let collections):
self?.collections = collections
case .failure(let error):
print("Error fetching collections: \(error.localizedDescription)")
}
}
}
}
}
数据库服务
func getUserCollections(userID: String, completion: @escaping (Result<[VenueCollection], Error>) -> Void){
let userPrivateCollectionsRef = Firestore.firestore().collection("users").document(userID).collection("private_collections")
userPrivateCollectionsRef.getDocuments { snapshot, error in
if let error = error {
print("Error fetching collections: \(error.localizedDescription)")
completion(.failure(error))
return
}
let fetchedCollections: [VenueCollection] = snapshot?.documents.compactMap { document in
try? document.data(as: VenueCollection.self)
} ?? []
completion(.success(fetchedCollections))
}
}
查看
struct CollectionsListView: View {
@EnvironmentObject var authViewModel: AuthViewModel
@Binding var showCreateCollection: Bool
var body: some View {
List {
ForEach (authViewModel.collections) { collection in
CollectionsRowView(venueCollection: collection)
.background(
NavigationLink("", destination: CollectionView(venueCollection: collection))
.opacity(0)
)
.listRowSeparator(.hidden)
}
Button {
showCreateCollection = true
} label: {
PrimaryButtonActiveToggle(isActive: true, ButtonText: "Create collection")
.padding(.horizontal)
}
.listRowSeparator(.hidden)
}
.listStyle(PlainListStyle())
.onAppear(){
authViewModel.getUserCollections()
}
}
创建集合后,函数会将集合写入 firebase。然后,我重新调用 getUserCollections 函数并取消创建集合视图。将数据打印到控制台显示集合计数增加。但列表不会更新,直到导航离开并返回到视图,可能会触发 onAppear getUserCollections,这一次有效。
我不明白为什么,即使从 Firebase 获取数据有延迟,列表也不会随数组更新。
我还尝试乐观地用新场地更新本地数组,但这也没有更新列表。
希望我分享了足够多/没有太多代码。感谢任何帮助。
修复了问题 - 由于某种原因,我在呈现创建类别视图时创建了视图模型的新实例:
sheet(isPresented: $showCreateCollection) {
NewCollectionView(isPresented: $showCreateCollection)
.environmentObject(AuthViewModel(databaseService: DatabaseService())) }
很确定我实现这个是为了修复其他一些错误,但如果没有它,它似乎可以正常工作,并且只使用环境对象,因为它应该。