2017-11-24 6 views
0

Ich entwickle eine Eltern-App in Swift, ich benutze Firebase Cloud Firestore, um Daten für meine Swift App zu speichern. In einem Teil der App können Eltern ihre Kinder hinzufügen und in der App anzeigen.Swift Firestore - Löschen Zelle Zelle und Dokument aus Firestore entfernen

Ich habe ein Child-Modell erstellt, das ich benutze, wenn ich meinem Tableview ein neues Kind hinzufüge.

Child Modell

protocol DocumentSerializable { 
    init?(dictionary:[String:Any]) 
} 

// Child Struct 
struct Child { 

    var name: String 
    var age: Int 
    var timestamp: Date 
    var imageURL: String 

    var dictionary:[String:Any] { 
     return [ 
      "name":name, 
      "age":age, 
      "timestamp":timestamp, 
      "imageURL":imageURL 
     ] 
    } 

} 

//Child Extension 
extension Child : DocumentSerializable { 
    init?(dictionary: [String : Any]) { 
     guard let name = dictionary["name"] as? String, 
      let age = dictionary["age"] as? Int, 
      let imageURL = dictionary["imageURL"] as? String, 
      let timestamp = dictionary["timestamp"] as? Date else { 
       return nil 
     } 
     self.init(name: name, age: age, timestamp: timestamp, imageURL: imageURL) 
    } 
} 

ich Daten zu meinem Tableview in meiner Anwendung hinzufügen, indem Sie eine Funktion aus meiner Sicht haben Last läuft, loaddata()

Ich habe 2 Variablen oberhalb dieser ersten:

//firestore connection 
var db:Firestore! 

//child array 
var childArray = [Child]() 

viewDidLoad

Die Funktion loadData() stellt eine Verbindung zu den Daten der eingeloggten Benutzer her, erfasst dann die Dokumente der untergeordneten Benutzer und fügt die untergeordneten Elemente mit dem Child Object-Protokoll zum childArray hinzu.

func loadData() { 
     // create ref to generate a document ID 
     let user = Auth.auth().currentUser 
     db.collection("users").document((user?.uid)!).collection("children").getDocuments() { 
      QuerySnapshot, error in 
      if let error = error { 
       print("\(error.localizedDescription)") 
      } else { 
       // get all children into an array 
       self.childArray = QuerySnapshot!.documents.flatMap({Child(dictionary: $0.data())}) 
       DispatchQueue.main.async { 
        self.childrenTableView.reloadData() 
       } 
      } 
     } 
    } 

Ich erhalte die numberOfRowsInSection durch die childArray wie so zählen Rückkehr:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return childArray.count 
    } 

ich bevölkern die cellForRow eine benutzerdefinierte Zelle-Klasse und mit den childArray Inhalt wie folgt:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = childrenTableView.dequeueReusableCell(withIdentifier: "Cell") as! ChildCellTableViewCell 
     let child = childArray[indexPath.row] 

     cell.childNameLabel.text = "\(child.name)" 
     cell.childAgeLabel.text = "Age: \(child.age)" 

     let url = URL(string: "\(child.imageURL)") 
     cell.childImage.kf.setImage(with: url) 

     cell.childNameLabel.textColor = UIColor.white 
     cell.childAgeLabel.textColor = UIColor.white 
     cell.backgroundColor = UIColor.clear 

     return cell 
    } 

Ich möchte in der Lage sein, zu wischen, um jede Tabellenzeilenzelle zu löschen, so dass ich Folgendes implementiert habe:

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { 
     return true 
    } 

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { 
     if (editingStyle == UITableViewCellEditingStyle.delete) { 

      childArray.remove(at: indexPath.row) 
      tableView.deleteRows(at: [indexPath], with: .fade) 

     } 
    } 

Dadurch wird die Zeile erfolgreich aus der App entfernt. Aber mein Problem ist ich bin nicht sicher, wie man die gelöschte Reihe erhält, um die übereinstimmenden Daten von der Firestore Datenbank zu löschen.

Und um die Dinge noch mehr zu komplizieren, da jedes Kind ein Bild hat, das in Firebase Storage gespeichert wird, muss ich irgendwie auch dieses Bild löschen. Die Bild-URL wird im Children-Dokument unter imageURL gespeichert.

Ich würde mich über jede Anleitung oder Hinweise in die richtige Richtung dafür freuen, ich kann nicht viel Dokumentation in Bezug auf Firestore und UITableViews finden, also weiß nicht, was ich als nächstes versuchen soll?


UPDATE Im Funktion ‚canEditRow‘ ich es geschafft haben, die Childs Bild von Firebase Speicher aus dem Tabellenzeile I gelöscht zu löschen, aber ich habe Schwierigkeiten, das Kind Dokument von Firestore zu löschen. Ich kann das zu löschende Dokument abfragen, bin aber nicht sicher, wie ich die delete() -Funktion von dieser Abfrage aus ausführen soll.

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { 
     if (editingStyle == UITableViewCellEditingStyle.delete) { 

      // 1. First Delete the childs image from storage 
      let storage = Storage.storage() 
      let childsImageURL = childArray[indexPath.row].imageURL 
      let storageRef = storage.reference(forURL: childsImageURL) 

      storageRef.delete { error in 
       if let error = error { 
        print(error.localizedDescription) 
       } else { 
        print("File deleted successfully") 
       } 
      } 


      // 2. Now Delete the Child from the database 
      let name = childArray[indexPath.row].name 

      let user = Auth.auth().currentUser 
      let query = db.collection("users").document((user?.uid)!).collection("children").whereField("name", isEqualTo: name) 

      print(query) 


      childArray.remove(at: indexPath.row) 
      tableView.deleteRows(at: [indexPath], with: .fade) 

     } 
    } 

Antwort

0

Ich glaube, ich habe es geschafft, dies heraus zu arbeiten, und es scheint zu funktionieren.In der "canEditRow" Funktion, Nummer 2, kann ich jetzt das bestimmte Kind (beim Streichen der zu löschenden Tabellenzelle) und es löscht das gleiche in Firebase Firestore Database.

Ich bin mir nicht sicher, ob dies der richtige Weg ist, oder ob mir eine Fehlerüberprüfung fehlt, aber alles scheint zu funktionieren.

Wenn jemand hier Fehler entdecken kann, lassen Sie es mich bitte wissen, ich möchte wirklich sicherstellen, dass es sicher zu bedienen ist und alle Fallbacks vorhanden sind.

Also hier ist was ich getan habe, um die ganze Sache arbeiten zu lassen.

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { 
     if (editingStyle == UITableViewCellEditingStyle.delete) { 

      // 1. First Delete the childs image from storage 
      let storage = Storage.storage() 
      let childsImageURL = childArray[indexPath.row].imageURL 
      let storageRef = storage.reference(forURL: childsImageURL) 

      storageRef.delete { error in 
       if let error = error { 
        print(error.localizedDescription) 
       } else { 
        print("File deleted successfully") 
       } 
      } 



      // 2. Now Delete the Child from the database 
      let name = childArray[indexPath.row].name 
      let user = Auth.auth().currentUser 
      let collectionReference = db.collection("users").document((user?.uid)!).collection("children") 
      let query : Query = collectionReference.whereField("name", isEqualTo: name) 
      query.getDocuments(completion: { (snapshot, error) in 
       if let error = error { 
        print(error.localizedDescription) 
       } else { 
        for document in snapshot!.documents { 
         //print("\(document.documentID) => \(document.data())") 
         self.db.collection("users").document((user?.uid)!).collection("children").document("\(document.documentID)").delete() 
       } 
      }}) 


      // 3. Now remove from TableView 
      childArray.remove(at: indexPath.row) 
      tableView.deleteRows(at: [indexPath], with: .fade) 

     } 
    }