SwiftUI:如何遍历Cloud Firestore Collection中的文档并获取数据? [英] SwiftUI: How to iterate over Documents in Cloud Firestore Collection and get Data?

查看:52
本文介绍了SwiftUI:如何遍历Cloud Firestore Collection中的文档并获取数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have this small project where a user can post an Image together with a quote, I would then like to display the Image and the quote togehter in their profile, as well as somewhere else so other users can see the post.

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

If I have this Cloud Firestore setup where all of the Image Docs have the same 3 fields, but with different values.

然后如何遍历所有图像文档,并获得网址报价?因此,我以后可以将URL与正确的Quote一起显示吗?

How can I then iterate over all of the Image Docs and get the the Url and the quote? So I later can display the url together with the correct Quote?

如果由于某种原因无法做到这一点,那么是否有可能获得馆藏中的文件数量?

And if this is for some reason not possible, is it then possible to get the number of Documents in a Collection?

顺便说一句,我不是很有经验,所以我很感激孩子友好".尽可能回答

BTW, I am not very experienced so I would appreciate a "kid friendly" answer if possible

推荐答案

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 获得集合中的所有文档.

You can get all of the documents in a collection by calling getDocuments.

此外,快照将是可选的-如果查询成功,它将返回数据.您可以在 guard 语句中看到我打包 snapshot 并检查 error 的情况.

Inside that, snapshot will be an optional -- it'll return data if the query succeeds. You can see I upwrap snapshot and check for error in the guard statement.

一旦有了快照,就可以使用 documents.forEach 遍历文档.在每个文档上,调用 data()将为您提供 [String:Any] 类型的字典.

Once you have the snapshot, you can iterate over the documents with documents.forEach. On each document, calling data() will get you a Dictionary of type [String:Any].

然后,您可以从字典中请求键,然后尝试将其强制转换为 String .

Then, you can ask for keys from the dictionary and try casting them to String.

您现在可以哭了,我正在将所有数据打印到控制台上.

You can wee that right now, I'm printing all the data to the console.

请记住, getDocuments 异步函数.这意味着它将运行,然后在将来的未指定时间返回.这意味着您可以返回这些函数中的值,并期望它们在调用后立即可用.取而代之的是,您必须依靠设置属性以及可能使用回调函数或Combine来告知程序的其他部分已接收到此数据的事情.

Keep in mind that getDocuments is an asynchronous function. That means that it runs and then returns at an unspecified time in the future. This means you can just return values out of this function and expect them to be available right after the calls. Instead, you'll have to rely on things like setting properties and maybe using callback functions or Combine to tell other parts of your program that this data has been received.

如果这是在SwiftUI中,则可以通过使用视图模型然后显示获取的数据来实现:

If this were in SwiftUI, you might do this by having a view model and then displaying the data that is fetched:

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中解码出来,但这超出了此答案的范围,后者显示了基本知识

这篇关于SwiftUI:如何遍历Cloud Firestore Collection中的文档并获取数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆