繁体   English   中英

如何在 SwiftUI 的不同视图中更新 Cloud Firestore 中的数据?

[英]How to update data in Cloud Firestore in different views for SwiftUI?

我有多个视图,并希望在点击按钮时在每个不同视图中对 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")
          }
        }
      }
    }
  }

一些注意事项:

  1. Swift 中的类名应以大写字母开头,因此您的视图应命名为FirstViewSecondView
  2. 您应该考虑使用实现Codable协议的struct来实现数据对象,而不是将您的文档 ( firestorePost ) 组装为字典:
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 结合使用的更多背景知识:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM