簡體   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