繁体   English   中英

SwiftUI:如何遍历 Cloud Firestore 集合中的文档并获取数据?

[英]SwiftUI: How to iterate over Documents in Cloud Firestore Collection and get Data?

我有一个小项目,用户可以在其中发布图片和报价,然后我想在他们的个人资料以及其他地方显示图片和报价,以便其他用户可以看到该帖子。

如果我有这个 Cloud Firestore 设置,其中所有图像文档都具有相同的 3 个字段,但具有不同的值。

然后如何遍历所有图像文档并获得Url报价 所以我以后可以显示 url 和正确的报价? 在此处输入图像描述

如果由于某种原因这是不可能的,那么是否可以获得集合中的文档数量?

顺便说一句,我不是很有经验,所以如果可能的话,我会很感激“孩子友好”的回答

Firestore
  .firestore()
  .collection("Images")
  .getDocuments { (snapshot, error) in
     guard let snapshot = snapshot, error == nil else {
      //handle error
      return
    }
    print("Number of documents: \(snapshot.documents.count ?? -1)")
    snapshot.documents.forEach({ (documentSnapshot) in
      let documentData = documentSnapshot.data()
      let quote = documentData["Quote"] as? String
      let url = documentData["Url"] as? String
      print("Quote: \(quote ?? "(unknown)")")
      print("Url: \(url ?? "(unknown)")")
    })
  }

您可以通过调用getDocuments来获取集合中的所有文档。

在其中, snapshot将是可选的——如果查询成功,它将返回数据。 您可以看到我对snapshot进行了包装并检查了guard语句中的error

获得快照后,您可以使用 documents.forEach 遍历documents.forEach 在每个文档上,调用data()会得到一个[String:Any]类型的字典。

然后,您可以从字典中请求键并尝试将它们转换为String

您现在可以看到,我正在将所有数据打印到控制台。

请记住, getDocuments是一个异步function。 这意味着它会运行,然后在未来的某个未指定时间返回。 这意味着您可以从 function 中return值,并期望它们在调用后立即可用。 相反,您将不得不依赖诸如设置属性之类的东西,并且可能使用回调函数或组合来告诉程序的其他部分已收到此数据。

如果这是在 SwiftUI 中,您可以通过查看 model 然后显示获取的数据来执行此操作:

struct ImageModel {
  var id = UUID()
  var quote : String
  var url: String
} 

class ViewModel {
  @Published var images : [ImageModel] = []

  func fetchData() { 
    
    Firestore
   .firestore()
   .collection("Images")
   .getDocuments { (snapshot, error) in
      guard let snapshot = snapshot, error == nil else {
      //handle error
      return
    }
    print("Number of documents: \(snapshot.documents.count ?? -1)")
    self.images = snapshot.documents.compactMap { documentSnapshot -> ImageModel? in
      let documentData = documentSnapshot.data()
      if let quote = documentData["Quote"] as? String, let url = documentData["Url"] as? String {
         return ImageModel(quote: quote, url: url)
      } else {
         return nil
      }
    }
   }
  }
}

struct ContentView {
  @ObservedObject var viewModel = ViewModel()

  var body : some View {
    VStack {
      ForEach(viewModel.images, id: \.id) { item in 
        Text("URL: \(item.url)")
        Text("Quote: \(item.quote)")
      }
    }.onAppear { viewModel.fetchData() }
  }
} 

注意:现在有更好的方法可以使用 FirebaseFirestoreSwift 和 Combine 从 Firestore 解码对象,但这有点超出这个答案的 scope,它显示了基础知识

暂无
暂无

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

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