删除 SwiftUI 后 Firebase Firestore 不更新 UI
Posted
技术标签:
【中文标题】删除 SwiftUI 后 Firebase Firestore 不更新 UI【英文标题】:Firebase Firestore doesn't update UI after deletion SwiftUI 【发布时间】:2021-08-16 05:23:21 【问题描述】:我正在尝试通过 SwiftUI 从我的 Firestore 数据库中删除一个对象,并且数据已成功删除。但是它不会在我的 UI 中更新,除非我手动重新加载它。
现在,我正在使用 @Environment(\.presentationMode) var presentation
在删除完成后关闭视图。
这是我的 Firebase 代码:
func deleteData(category: String,completion: @escaping (success) -> Void)
db.collection("passwords").document("\(Auth.auth().currentUser!.uid)").getDocument(snapshot, error) in
guard let snapshot = snapshot, error == nil else
return
let documentID = snapshot.data()!["date"] as! String
db.collection("passwords").document("\(Auth.auth().currentUser!.uid)").collection(documentID).document("\(category)").delete() err in
if let err = err
print("Error removing document: \(err)")
completion(false)
else
print("Document successfully removed!")
completion(true)
这是 SwiftUI 代码:
@Environment(\.presentationMode) var presentation
var body: some View
ForEach(self.data)item in
HStack
Text(item.category)
Spacer()
Button(action:
deleteData(category: item.category!)
(success) -> Void in
if success
print("deleted successfully")
self.presentation.wrappedValue.dismiss()
)
Text("Delete")
.onAppear
fetchData()
class FirebaseData: ObservableObject
@State var id: String?
@State var category: String
@State var password: String
init(id: String?, password: String, category: String)
self.id = id
self.password = password
self.category = category
self.data
来自@State var data: [FirebaseData] = []
。
【问题讨论】:
除非显示相关代码,否则无法调试。 我的错,我编辑后忘记保存代码了,现在可以了:) 相关代码仍然没有。什么填充 self.data?它不会在 deleteData 中被操纵,因此它不会被更新是合理的。 data 是一个 Firebase 类,从 Firestore 中检索。是的,deleteData 从 Firestore 中删除了该特定数据,但它不会在 UI 上更新,除非我手动刷新它 您没有显示 self.data 的设置或操作位置,因此无法调试。 【参考方案1】:这里有几个问题:
一般来说,在进行异步工作时,您可能希望在ObservableObject
中进行,而不是在View
本身中进行——我已将代码移至视图模型中。
你的模型不应该是ObservableObject
——它应该只是一个结构。在ObservableObject
上使用@State
无论如何都不会做任何事情——使用ObservableObject
时使用@Published
值
您正在使用 getDocument
获取数据一次,这就是您的 UI 没有更新的原因。如果您希望 UI 更新,请使用快照侦听器:https://firebase.google.com/docs/firestore/query-data/listen
struct FirebaseData
var id: String?
var category: String
var password: String
class ViewModel : ObservableObject
@Published var data : [FirebaseData] = []
private let db = Firestore.firestore()
private var listener : ListenerRegistration?
func fetchData()
db.collection("passwords").document("\(Auth.auth().currentUser!.uid)")
.getDocument(snapshot, error) in
guard let snapshot = snapshot, error == nil else
return
let documentID = snapshot.data()!["date"] as! String
self.listener = self.db.collection("passwords").document("\(Auth.auth().currentUser!.uid)").collection(documentID)
.addSnapshotListener() (querySnapshot, err) in //<-- Here
if let err = err
print("Error getting documents: \(err)")
else
self.data = (querySnapshot?.documents ?? []).map
FirebaseData(id: $0.documentID,
category: $0.data()["category"] as? String ?? "",
password: $0.data()["password"] as? String ?? "")
func deleteData(category: String,completion: @escaping (success) -> Void)
db.collection("passwords").document("\(Auth.auth().currentUser!.uid)").getDocument(snapshot, error) in
guard let snapshot = snapshot, error == nil else
return
let documentID = snapshot.data()!["date"] as! String
self.db.collection("passwords").document("\(Auth.auth().currentUser!.uid)").collection(documentID).document("\(category)").delete() err in
if let err = err
print("Error removing document: \(err)")
completion(false)
else
print("Document successfully removed!")
completion(true)
struct ContentView: View
@Environment(\.presentationMode) var presentation
@StateObject private var viewModel = ViewModel()
var body: some View
NavigationView
ForEach(viewModel.data, id: \.self.id) item in
HStack
Text(item.category)
Spacer()
Button(action:
viewModel.deleteData(category: item.category)
(success) -> Void in
if success
print("deleted successfully")
)
Text("Delete")
.onAppear
viewModel.fetchData()
我还要做一些重构,例如:
-
确保您没有在任何地方使用
!
来强制展开 - 这可能会导致崩溃
存储文档 ID,这样您就不会在 deleteData
中进行其他查询
但是,这应该让你现在就开始。
【讨论】:
太棒了!谢谢,你是一个救生员:)以上是关于删除 SwiftUI 后 Firebase Firestore 不更新 UI的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 SwiftUI 从 Firebase / Firestore 中删除文档
SwiftUI Firebase。删除所有项目而不仅仅是一个