【问题标题】:How to update data in Cloud Firestore in different views for SwiftUI?如何在 SwiftUI 的不同视图中更新 Cloud Firestore 中的数据?
【发布时间】:2021-01-03 03:55:47
【问题描述】:

我有多个视图,并希望在点击按钮时在每个不同的视图中更改 Firestore 数据库。

firstView 中,我已将数据设置为 Firestore,并希望在点击按钮时在第二个视图中更新它们。

我注意到我不能在每个不同的视图中调用 Firestore。

作为初学者,如何在不同的视图中实现数据更新?

  import SwiftUI
  import Firebase

  struct firstView: View {
    var body: some View {
      VStack {
        Text("Greetings!")
            
        Button(action: {
          self.writeDatabase()
        }) {
          Text("Next")
        }
      }
    }

    func writeDatabase() {
      let firestoreDatabase = Firestore.firestore()
    
      let firestorePost = [
        "PostedBy": Auth.auth().currentUser!.email!,
        "date": FieldValue.serverTimestamp(), 
        "CityName": "", 
        "DistrictName": ""] as [String : Any]

      firestoreDatabase
        .collection("Posts")
        .document("Dc")
        .setData(firestorePost, merge: true) { error in
        if error != nil {
          print("error")
        }
      }
    }
  }

我的第二种看法如下:

  import SwiftUI
  import Firebase

  struct secondView: View {
    var body: some View {
      NavigationView {
        VStack {
          Text("Tap to update...")
                
          NavigationLink(destination: good()) {
            Text("Next")
          }
          .onAppear {
            self.update()
          }
        }
      }
    }

    func update() {
        let firestoreDatabase = Firestore.firestore()
        firestoreDatabase
          .collection("Posts")
          .document("Dc")
          .updateData(
            [
              "CityName" : "İstanbul", 
              "DistrictName": "Beşiktaş"
            ]
          ) { (error) in
          if error != nil{
            print("Error")
          }
          else {
            print("succesfully updated")
          }
        }
      }
    }
  }

【问题讨论】:

    标签: swift firebase google-cloud-firestore swiftui


    【解决方案1】:

    几点说明:

    1. Swift 中的类名应该以大写字母开头,所以你的视图应该命名为FirstViewSecondView
    2. 不应将文档 (firestorePost) 组装为字典,而应考虑使用实现 Codable 协议的 struct 来实现数据对象:
    struct Post: Codable {
      var postedBy: String
      var cityName: String
      var districtName: String
    }
    
    1. 然后您就可以更轻松地添加和更新此struct 的实例:
      private func addPost(_ post: Post) {
        do {
          let _ = try db.collection("posts").addDocument(from: post)
        }
        catch {
          print(error)
        }
      }
    
      private func updatePost(_ post: Post) {
        if let documentId = post.id {
          do {
            try db.collection("posts").document(documentId).setData(from: post)
          }
          catch {
            print(error)
          }
        }
      }
    
    1. 此外,检索这些帖子会更容易(再次感谢Codable):
    class PostsViewModel: ObservableObject {
      @Published var posts = [Post]()
      
      private var db = Firestore.firestore()
      private var listenerRegistration: ListenerRegistration?
      
      deinit {
        unsubscribe()
      }
      
      func unsubscribe() {
        if listenerRegistration != nil {
          listenerRegistration?.remove()
          listenerRegistration = nil
        }
      }
      
      func subscribe() {
        if listenerRegistration == nil {
          listenerRegistration = db.collection("posts").addSnapshotListener { (querySnapshot, error) in
            guard let documents = querySnapshot?.documents else {
              print("No documents")
              return
            }
            
            self.posts = documents.compactMap { queryDocumentSnapshot in
              try? queryDocumentSnapshot.data(as: Post.self)
            }
          }
        }
      }
    }
    
    1. 最后,尽量不要将任何数据访问逻辑放入您的视图中。而是将它们提取到视图模型中。然后,您可以将视图连接到其视图模型,并将其添加为观察对象,如下所示:
    @StateObject var viewModel = PostsViewModel()
    

    查看这些文章,这些文章提供了有关如何将 SwiftUI 与 Cloud Firestore 结合使用的更多背景信息:

    【讨论】:

    • 谢谢您,先生,我按照您的建议更改了密码。我可以在 FirstView 中写入和更改 Cloud Firestore,但无法在 secondView 中更新。相关代码、视图模型和模型在此链接github.com/ozanones/deneme。 firstView = howyoufeel.swift , secondView = lokasyonView
    • 我们解决了与我分享的 GitHub 存储库 Ozan 中的问题。 (在此处拉取请求:github.com/ozanones/firestoredeneme/pull/3
    猜你喜欢
    • 1970-01-01
    • 2021-09-26
    • 1970-01-01
    • 2023-03-22
    • 2019-07-12
    • 1970-01-01
    • 2021-05-15
    • 2019-09-14
    • 1970-01-01
    相关资源
    最近更新 更多