如何使用 SwiftUI 中的 documentID 删除特定的 Cloud Firestore 文档?

Posted

技术标签:

【中文标题】如何使用 SwiftUI 中的 documentID 删除特定的 Cloud Firestore 文档?【英文标题】:How can I delete a specific Cloud Firestore document using the documentID in SwiftUI? 【发布时间】:2020-08-26 14:54:29 【问题描述】:

我正在使用列表来显示用户通过表单输入的伤害数据,该表单已成功添加到 Cloud Firestore。我现在想添加一个删除功能,删除列表中选择的伤害。

这是我的Injury结构:

import SwiftUI
import FirebaseFirestoreSwift

struct Injury: Identifiable, Codable 
  @DocumentID var id: String? = UUID().uuidString
  var userId: String?
  var specificLocation: String
  var comment: String
  var active: Bool
  var injuryDate: Date
  var exercises: String
  var activity: String
  var location: String    

我的InjuriesViewModel

import SwiftUI
import Firebase
import FirebaseFirestore
import FirebaseFirestoreSwift

class InjuriesViewModel: ObservableObject     
  @Published var injuries = [Injury]()
    
  private var db = Firestore.firestore()

  func fetchData () 
    let userId = Auth.auth().currentUser?.uid
    
    db.collection("injuries")
      .order(by: "injuryDate", descending: true)
      .whereField("userId", isEqualTo: userId)
      .addSnapshotListener (querySnapshot, error) in
        guard let documents = querySnapshot?.documents else 
          print("no documents")
          return
        
                
        self.injuries = documents.compactMap  (queryDocumentSnapshot) -> Injury? in
          return try? queryDocumentSnapshot.data(as: Injury.self)
        
    
  

我的InjuryViewModel(这里是添加和删除伤害功能的地方,但是我不知道如何填写文档字段):

import SwiftUI
import Firebase

class InjuryViewModel: ObservableObject     
  @Published var injury: Injury = Injury(id: "", userId: "", specificLocation: "", comment: 
    "", active: false, injuryDate: Date(), exercises: "", activity: "", location: "")
    
  private var db = Firestore.firestore()

  func addInjury(injury: Injury) 
    do 
      var addedInjury = injury
      addedInjury.userId = Auth.auth().currentUser?.uid
      let _ = try db .collection("injuries").addDocument(from: addedInjury)
    
    catch 
      print(error)
    
  
      
  func deleteInjury(injury: Injury) 
    db.collection("injury").document(??).delete()  err in
      if let err = err 
        print("Error removing document: \(err)")
       
      else 
        print("Document successfully removed!")
      
    
  
    
  func save () 
    addInjury(injury: injury)
  
    
  func delete () 
    deleteInjury(injury: injury)
  

提前感谢您的帮助!

这是我所在的位置:

  func addInjury(injury: Injury)         
    do 
      var addedInjury = injury
      addedInjury.userId = Auth.auth().currentUser?.uid
      let documentRef = try db.collection("injuries").addDocument(from: addedInjury)
      addedInjury.id = documentRef.documentID
      print(documentRef.documentID)
    
    catch 
      print(error)
    
  

  func deleteInjury(injury: Injury) 
    db.collection("injuries").document(injury.id!).delete()  err in
    if let err = err 
      print("Error removing document: \(err)")
    
    else 
      print("Document successfully removed!")
    
  

【问题讨论】:

如果您不知道文档 ID,您将无法删除该文档。您要么必须在调用 addDocument(它返回一个 DocumentReference)后记住它,要么查询文档库而不知道其字段的内容以获取删除它的 ID . 谢谢@DougStevenson。您能告诉我如何保存文档参考吗?我添加了一张我的 firebase 的照片,它没有存储“id”。谢谢 您当前正在使用let _ = ... 保存生成的文档引用。之后你用它做什么取决于你。它有一个 documentID 属性,其中包含新创建的文档的 ID。 【参考方案1】:

deleteInjury 中,您只需要访问您的视图模型所持有的当前InjurydocumentID

func deleteInjury(injury: Injury) 
  db.collection("injury").document(injury.id).delete()  err in
    if let err = err 
      print("Error removing document: \(err)")
     
    else 
      print("Document successfully removed!")
    
  

【讨论】:

谢谢彼得,总的来说,我对 firebase 和 Swift 很陌生,你的视频很棒。非常感谢您的帮助。我仍然无法将 id 保存在 firebase 文档中。我已经更新了上面的函数 documentRef.documentID 在控制台打印成功。 您可以尝试在您的视图中使用@StateObject 代替@ObservableObject 吗?我怀疑 SwiftUI 正在重新创建您的视图模型,并且在这样做的项目中破坏了 @Published injury 实例。 @JoshAllen 有帮助吗? 我还没有更新到 Xcode 12 和 Swift 2.0,我相信我需要这些才能使用 @StateObject。我会更新,看看是否能解决问题。再次感谢!

以上是关于如何使用 SwiftUI 中的 documentID 删除特定的 Cloud Firestore 文档?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用核心数据将对象传递给 SwiftUI 中的其他视图

带有 SceneKit 的 SwiftUI:如何使用视图中的按钮操作来操作底层场景

如何在 swiftui 中弹出到 TabView 应用程序中的特定视图。我也使用了 StackNavigation 但不在 swiftui 中工作

如何正确处理更新视图中的选取器(SwiftUI)

如何从 SwiftUI 中的 Bundle 中的有效路径或 URL 将图像加载到 Image()?

如何在 SwiftUI 的 ScrollView 中制作动画? SwiftUI 中的手风琴风格动画