Search code examples
firebasegoogle-cloud-firestoreswiftuiswiftui-list

How do I delete a Firestore Document from a List in SwiftUI


Here is my view model

import FirebaseFirestore
import FirebaseFirestoreSwift

struct Todo: Codable, Identifiable, Hashable {
    @DocumentID var id: String?
    var todoDetais: String?
}

This is how I'm showing the list ignore the typo in "details".

var body: some View {
    NavigationView {
        List {
            ForEach(viewModel.todos, id: \.self) { todo in
                VStack{
                    Text(todo.todoDetais!)
                }
            }
            .onDelete(perform: delete)
        }

My fetch data and mapping.

    func fetchData() {
    db.collection("todos").addSnapshotListener { (querySnapshot, error) in
        guard let documents = querySnapshot?.documents else {
            print("No documents")
            return
        }
        
        self.todos = documents.map { (QueryDocumentSnapshot)  -> Todo in
            let data = QueryDocumentSnapshot.data()
            let todoDetails = data["todo"] as? String ?? ""
            
            return Todo(todoDetais: todoDetails)
        }
    }
}

The delete logic, I can remove from a list but how do I delete from Firestore?

    func delete(at offsets: IndexSet) {
    viewModel.todos.remove(atOffsets: offsets)
    
    //I need to delete a firestore document at the index im removing at?
    
}

Solution

  • You can map the offsets to your Todo models by doing this:

    offsets.map { viewModel.todos[$0] }
    

    So, your delete function might look something like this:

    func delete(at offsets: IndexSet) {
      offsets.map { viewModel.todos[$0] }.forEach { todo in 
        guard let todoID = todo.id else { return }
        db.collection("todos").document(todoID).delete() { err in
          if let err = err {
            print("Error removing document: \(err)")
          } else {
            print("Document successfully removed!")
          }
        }
      }
    }
    

    If you had a bunch, you could look into batching the requests, but this should get you started.