如何使用 SwiftUI 更新 Firebase 中的集合?

Posted

技术标签:

【中文标题】如何使用 SwiftUI 更新 Firebase 中的集合?【英文标题】:How to update collection in Firebase using SwiftUI? 【发布时间】:2021-03-09 04:19:32 【问题描述】:

我正在开发 SwiftUI 上的患者/库存管理软件,我决定放弃 CoreData 以使用 Firebase。这似乎不那么麻烦,但对于初学者来说,这仍然是一个学习曲线。开发人员最初帮助我创建并获取 API 患者文件中的患者,但现在我正在尝试更新数据,我似乎无法弄清楚要写什么......

我浏览了多个教程,它们似乎都在使用 db.collection 做事的方式。

这是我的代码

import Foundation
import FirebaseFirestore
class PatientAPI 
    
    func createPatient(firstName: String, lastName: String, address: String, postCode: String, phoneNumber: String, onSuccess: @escaping(_ successMessage: String) -> Void) 
     
        let testPatient = PatientModel.init(firstName: firstName, lastName: lastName, address: address, postalCode: postCode, phoneNumber: phoneNumber)
       
        
        
        guard let dict = try? testPatient.toDictionary() else return /
       
        API.FIRESTORE_COLLECTION_PATIENTS.addDocument(data: dict)
        onSuccess("Done")
    
    

    
    func getPatients(onSuccess: @escaping(_ patients: [PatientModel]) -> Void, onError: @escaping(_ errorMesage: String) -> Void) 
        
       
        API.FIRESTORE_COLLECTION_PATIENTS.getDocuments  (snapshot, error) in
            if let error = error 
                onError(error.localizedDescription)
                return
            
            
            
            guard let snap = snapshot else return
            
            var patients = [PatientModel]()
            
            
           
            for document in snap.documents 
                let dict = document.data()
                guard let decodedPatient = try? PatientModel.init(fromDictionary: dict) else return
                patients.append(decodedPatient) 
                
            
            onSuccess(patients) 
        
    
 
   

非常感谢

【问题讨论】:

【参考方案1】:

我建议使用 Firebase 的 Codable 支持,因为这将使您的代码更具可读性和可维护性。

为此,您的Patient 应该是符合Codablestruct,如下所示:

struct Patient: Identifiable, Codable 
  @DocumentID var id: String?
  var firstName: String
  var lastName: String
  var address: String
  // ...

然后,要从集合中获取所有患者(或满足特定条件的患者),请使用 Firestore 的快照侦听器:

func fetchData() 
  db.collection("patients").addSnapshotListener  (querySnapshot, error) in
    guard let documents = querySnapshot?.documents else 
      print("No documents")
      return
    
      
    self.books = documents.compactMap  queryDocumentSnapshot -> Patient? in
      return try? queryDocumentSnapshot.data(as: Patient.self)
    
  

要添加新患者,首先创建一个新患者:

let patient = Patient(firstName: "Jane", lastName: "Appleseed", /* other attributes go here */)

然后像这样将它添加到集合中:

func addPatient(patient: Patient) 
  do 
    let _ = try db.collection("patients").addDocument(from: patient)
  
  catch 
    print(error)
  

在我的article here 中了解更多详情。

【讨论】:

我实际上一直在关注你的教程,如果我明白这一点,我有一个 API 文件,根据你的建议应该是我放入 PatientAPI 的 PatientRepository 和 func addPatient,我可以简单地放入我的 PatientViewModel 以及所有必要的功能(删除、更新等)。 所以存储库只是将所有数据访问相关代码封装在一个地方的好方法。在您的视图模型中,您将使用存储库的方法以视图需要的方式访问数据。随意整理要点并与我分享,以便我可以添加审查您的代码并回答更详细的问题。 当然,我会尽快处理的!非常感谢! 嗨,彼得,我按照你关于书籍和 firebase 的教程进行操作,非常有帮助,并且我设法很好地清理了我的代码。不幸的是,当我在 firestore 上添加集合时,我仍然无法更新应用程序 UI。我可以在哪里向您发送我的代码供您按照您之前的要求进行检查?谢谢! 随意在 GitHub 上创建一个(私有)repo 并与我分享。

以上是关于如何使用 SwiftUI 更新 Firebase 中的集合?的主要内容,如果未能解决你的问题,请参考以下文章

异步firebase调用后SwiftUI不更新变量

SwiftUI - 在 Firebase 上更新密码

在 Firebase 完成块中设置 @Published var 不更新 SwiftUI 视图

删除 SwiftUI 后 Firebase Firestore 不更新 UI

Firebase 和 swiftUI,监听实时更新奇怪的行为怪异

SwiftUI / Firebase:我可以使用@Published 向 Firebase 数据库发送和接收单个值吗?