Ios 在xcode中从SwiftUI视图更新Firestore数据不工作

Ios 在xcode中从SwiftUI视图更新Firestore数据不工作,ios,swift,google-cloud-firestore,swiftui,Ios,Swift,Google Cloud Firestore,Swiftui,所以我做了一个XCode项目,您可以在其中向Firestore添加数据,并通过搜索保存的数据(序列号)来读取数据。 我现在基本上尝试将这两个独立的视图(搜索视图+表单视图)结合起来,以获得第三个视图,在该视图中,您可以搜索“序列号”,而不是获取整个数据列表,而是获取包含数据的文本字段(与添加时的视图类似,只是字段中已经填充了存储的数据)。 因此,我的问题如下: 文本字段有点满了,但只有灰色的“占位符”文本。它们应该用可以编辑的普通文本填写,以防假人在编辑一行时按下save键,而整个数据都消失了

所以我做了一个XCode项目,您可以在其中向Firestore添加数据,并通过搜索保存的数据(序列号)来读取数据。 我现在基本上尝试将这两个独立的视图(搜索视图+表单视图)结合起来,以获得第三个视图,在该视图中,您可以搜索“序列号”,而不是获取整个数据列表,而是获取包含数据的文本字段(与添加时的视图类似,只是字段中已经填充了存储的数据)。 因此,我的问题如下:

  • 文本字段有点满了,但只有灰色的“占位符”文本。它们应该用可以编辑的普通文本填写,以防假人在编辑一行时按下save键,而整个数据都消失了
  • 如果我在文本字段中写入一些内容,然后按“Speichern”(“保存”),它总是会创建一个全新的文档(具有非常奇怪的ID样式([96251AF5-164A-4CBF-9BE6-9C9A482652DE]),而不是更改字段,而我整天都坐在这里,试图让它工作
整个代码是由两个不同的视频组合而成的。我希望你能帮助我(是的,我知道,它看起来很凌乱)

搜索栏+编辑快捷界面视图


import SwiftUI
import Firebase

struct ContentViewVier: View {
    
    @ObservedObject var data = getDataZwei()
    
    var body: some View {
       
        NavigationView{
            
            ZStack(alignment: .top){
                
                GeometryReader{_ in
                    
                    // Home View....
                    Text("Bitte Seriennummer eingeben").foregroundColor(.black)
                    
                }.background(Color("FarbeSeriennummerStartbildschirm").edgesIgnoringSafeArea(.all))
                
                CustomSearchBarEdit(data: self.$data.datas).padding(.top)
                
            }.navigationBarTitle("")
            .navigationBarHidden(true)
        }
    }
}


struct CustomSearchBarEdit : View {
    
    @State var txt = ""
    @Binding var data : [Gerät]
    
    var body : some View{
        
        VStack(spacing: 0){
            
            HStack{
                
                TextField("Nach Seriennummer suchen", text: self.$txt).opacity(100).foregroundColor(.black)
                
                if self.txt != ""{
                    
                    Button(action: {
                        
                        self.txt = ""
                        
                    }) {
                        
                        Text("Abbrechen")
                    }
                    .foregroundColor(.black)
                    
                }

            }.padding()
            
            if self.txt != ""{
                
                if
                    self.data.filter({$0.sn.lowercased() .contains(self.txt.lowercased())}).count == 0 {
                        
                    Text("Es wurde kein Gerät mit dieser Seriennummer gefunden").foregroundColor(Color.red.opacity(0.6)).padding()
                    
                }
                
                else{
                    
                    List(self.data.filter{$0.sn.contains(self.txt.lowercased())}){i in
                            
                    NavigationLink(destination: DetailZwei(data: i)) {
                        
                        Text(i.sn)
                    }
                         
                        Text(i.typ)
                    
                        
                    }.frame(height: UIScreen.main.bounds.height / 5)
                    
                }

            }
        
            
            
        }.background(Color.white)
        .padding()
    }
}

class getDataZwei : ObservableObject{
    
    @Published var datas = [Gerät]()
    
    init() {
        
        let db = Firestore.firestore()
        
        db.collection("Geräte").getDocuments { (snap, err) in
            
            if err != nil{
                
                print((err?.localizedDescription)!)
                return
            }
            
            for i in snap!.documents{
                
                let id = i.documentID
                let sn = i.get("Seriennummer") as! String
                let objekt = i.get("Objekt") as! String
                let str = i.get("Strasse") as! String
                let pos = i.get("Position") as! String
                let typ = i.get("Gerätetyp") as! String
                let ida = i.get("Installation")as! String
                let lg = i.get("LeasingOderGekauft")as! String
                let la = i.get("LeasingAblaufdatum")as! String
                let ga = i.get("GarantieAblaufdatum")as! String
                let nr = i.get("Hausnummer")as! String
                let plz = i.get("Postleitzahl")as! String
                let ort = i.get("Ort")as! String
                let vp = i.get("Verantwortlich")as! String
                let tel = i.get("Telefonnummer")as! String
                let zusatz = i.get("Zusätzlich")as! String
                
                self.datas.append(Gerät(id: id, sn: sn, objekt: pos, str: typ, nr: ida, ort: lg, vp: la, tel: ga, pos: objekt, typ: str, ida: nr, lg: plz, la: ort, ga: vp, zusatz: tel, plz: zusatz))
            }
        }
    }
}

struct dataTypeZwei : Identifiable, Codable {
    
    var id: String? = UUID().uuidString
    var sn : String
    var pos : String
    var typ : String
    var ida : String
    var lg : String
    var la : String
    var ga : String
    var objekt : String
    var str : String
    var nr : String
    var plz : String
    var ort : String
    var vp : String
    var tel : String
    var zusatz : String
}

struct DetailZwei : View {
    
   var data : Gerät
    @State var viewModel = GerätEditieren()
    @Environment(\.presentationMode) var presentationMode
    enum Mode {
      case new
      case edit
    }
    var mode: Mode = .edit
    
    
    var body : some View{
        
        NavigationView{
            
            ScrollView{
        
        VStack {
        
        Group{
        
            Text("Gerät")
                .font(.title)
            TextField(data.sn, text: $viewModel.gerät.sn).textFieldStyle(RoundedBorderTextFieldStyle())
                .navigationBarTitle("Geräteinformationen")
            TextField(data.objekt, text: $viewModel.gerät.objekt).textFieldStyle(RoundedBorderTextFieldStyle())
            TextField(data.typ, text: $viewModel.gerät.typ).textFieldStyle(RoundedBorderTextFieldStyle())
            TextField(data.pos, text: $viewModel.gerät.pos).textFieldStyle(RoundedBorderTextFieldStyle())
            Text("")
            TextField(data.ida, text: $viewModel.gerät.ida).textFieldStyle(RoundedBorderTextFieldStyle())
            TextField(data.lg, text: $viewModel.gerät.lg).textFieldStyle(RoundedBorderTextFieldStyle())
            TextField(data.la, text: $viewModel.gerät.la).textFieldStyle(RoundedBorderTextFieldStyle())
            TextField(data.ga, text: $viewModel.gerät.ga).textFieldStyle(RoundedBorderTextFieldStyle())
        }
            Group {
                
            Text("Adresse")
                .font(.title)
            TextField(data.str, text: $viewModel.gerät.str).textFieldStyle(RoundedBorderTextFieldStyle())
            TextField(data.nr, text: $viewModel.gerät.nr).textFieldStyle(RoundedBorderTextFieldStyle())
            TextField(data.plz, text: $viewModel.gerät.plz).textFieldStyle(RoundedBorderTextFieldStyle())
            TextField(data.ort, text: $viewModel.gerät.ort).textFieldStyle(RoundedBorderTextFieldStyle())
            }
            Group {
                
            Text("Kontakt")
                .font(.title)
            TextField(data.vp, text: $viewModel.gerät.vp).textFieldStyle(RoundedBorderTextFieldStyle())
            TextField(data.tel, text: $viewModel.gerät.tel).textFieldStyle(RoundedBorderTextFieldStyle())
            }
            
            Group {
                
            Text("Zusätzliche Informationen")
                .font(.title)
            TextField(data.zusatz, text: $viewModel.gerät.zusatz).textFieldStyle(RoundedBorderTextFieldStyle())
            }
            }.padding()
            .navigationBarTitle("Gerät hinzufügen", displayMode: .inline)
                    .navigationBarItems(leading: Button(action: { self.handleCancelTapped() }, label: {
                        Text("Abbrechen")
                    }),
                                        trailing: Button(action: { self.handleDoneTapped() }, label: {
                                            Text("Speichern")
                    })
                   // .disabled(!viewModel.modified)
                )
                }
            }
                }
                func handleCancelTapped() {
                dismiss()
                }
                func handleDoneTapped() {
                viewModel.save()
                 dismiss()
                }
                
                func dismiss() {
                    presentationMode.wrappedValue.dismiss()
                }
    }






struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentViewVier()
    }
}
查看模型

import Foundation
import Firebase
import Combine

class GerätEditieren: ObservableObject {
    
    @Published var gerät: Gerät = Gerät(sn: "", objekt: "", str: "", nr: "", ort: "", vp: "", tel: "", pos: "", typ: "", ida: "", lg: "", la: "", ga: "", zusatz: "", plz: "")
    
    private var db = Firestore.firestore()
    enum Mode {
      case new
      case edit
    }
    var mode: Mode = .edit
    
    
    /*
    private func addGerät(_ gerät: Gerät) {
         do{
    let _ = try db.collection("Geräte").addDocument(from: gerät)
         }
         catch {
             print(error)
         }
     }
    */
    
     
    private func updateGerät(_ gerät: Gerät) {
        if let ID = gerät.id {
         do {
        try db.collection("Geräte").document(ID).setData(from: gerät)
         }
         catch {
           print(error)
         }
       }
     }
    
    private func updateOrAddGerät() { // (1)
        if let _ = gerät.id {
            self.updateGerät(self.gerät) // (2)
      }
      else {
        print ("error") // (3)
      }
    }

    
    func save() {
        
        
        func updateGerät(_ gerät: Gerät) {
          if let ID = gerät.id {
           do {
          try db.collection("Geräte").document(ID).setData(from: gerät, merge: true)
           }
           catch {
             print(error)
           }
         }
       }
        
        updateOrAddGerät()

    }
        
}
另一种型号(有点)


为了更好地了解您的项目是如何设置的,您能否提供数据树的屏幕截图?查看本文,了解如何从SwiftUI应用程序构建应用程序并在Cloud Firestore中更新数据:您好,感谢您的回复。我已经能够解决我的问题。我使用的大部分代码来自Peter的教程(非常好)。问题是,我使用了“setData()”方法。要么我太笨了,要么这个方法不再有效。我改用了“updateData()”方法,效果很好。
import Foundation
import FirebaseFirestoreSwift

struct Gerät: Identifiable, Codable {
    var id: String? = UUID().uuidString
    var sn: String
    var objekt: String
    var str: String
    var nr: String
    var ort: String
    var vp: String
    var tel: String
    var pos: String
    var typ: String
    var ida: String
    var lg: String
    var la: String
    var ga: String
    var zusatz: String
    var plz: String
    
    enum CodingKeys: String, CodingKey {
        case sn = "Seriennummer"
        case objekt = "Objekt"
        case str = "Strasse"
        case nr = "Hausnummer"
        case ort = "Ort"
        case vp = "Verantwortlich"
        case tel = "Telefonnummer"
        case pos = "Position"
        case typ = "Gerätetyp"
        case ida = "Installation"
        case lg = "LeasingOderGekauft"
        case la = "LeasingAblaufdatum"
        case ga = "GarantieAblaufdatum"
        case zusatz = "Zusätzlich"
        case plz = "Postleitzahl"
    }
}