[英]firebase/firestore/lite doesn't work with firebase emulator?
[英]Firebase Firestore doesn't update UI after deletion SwiftUI
我正在尝试通过 SwiftUI 从我的 Firestore 数据库中删除 object 并且数据删除成功。 但是它不会在我的用户界面中更新,除非我手动重新加载它。
现在,我正在使用@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] = []
。
这里有几个问题:
通常,在执行异步工作时,您可能希望在ObservableObject
中执行它们,而不是在View
本身中执行——我已将代码移至视图 model 中。
您的 model 不应该是一个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()
}
}
}
}
我会做更多的重构,例如:
!
强制解包的任何地方——这可能会导致崩溃deleteData
中执行其他查询但是,这应该让你现在开始。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.