SWIFTUI Firebase 检索子集合数据

Posted

技术标签:

【中文标题】SWIFTUI Firebase 检索子集合数据【英文标题】:SWIFTUI Firebase Retrieving Subcollection Data 【发布时间】:2020-10-15 06:27:39 【问题描述】:

我明白,来自 firebase 的所有请求都是异步的。

我有收集任务类别 -> 文档 -> 子收集任务

这是我获取所有已创建任务类别的类,没有问题。问题是我需要通过传递文档 ID 来检索每个类别的所有任务。

class fsTasks: ObservableObject 
    
    @Published var categories = [fsTaskCategory]()
    
    init() 
        fsGetTaskCategories()
    
    
    /// Retrieve Tasks Categories For Logged In User
    func fsGetTaskCategories() 
        db.collection("tasksCategories").addSnapshotListener  (querySnapshot, error) in
            guard let documents = querySnapshot?.documents else 
                print("No documents")
                return
            
                        
            self.categories = documents.compactMap  queryDocumentSnapshot -> fsTaskCategory? in
                return try? queryDocumentSnapshot.data(as: fsTaskCategory.self)
            
        
    

我创建了另一个函数来检索每个传递的文档 ID 的所有任务

func fsGetTasks(documentID: String, completation: @escaping([fsTask]) -> Void) 
        
        var tasks = [fsTask]()
        
        db.collection("tasksCategories").document(documentID).collection("tasks").addSnapshotListener  (querySnapshot, error) in
            guard let documents = querySnapshot?.documents else 
                print("No documents")
                return
            
                        
            tasks = documents.compactMap  queryDocumentSnapshot -> fsTask? in
                return try? queryDocumentSnapshot.data(as: fsTask.self)
            
            
            completation(tasks)
        
    

问题是我不知道,如何在SWIFTUI视图中直接调用这个函数。

基本上我首先通过所有类别的ObservedObject进行ForEach,然后我需要为每个类别的所有任务做另一个foreach,但首先我需要检索数据。我需要一个函数,它返回一个数组,其中包含从 firebase 检索到的所有任务,但仅当完成处理程序返回数据时。

如果我有这样的功能

func retrieveAllTasks(categoryID: String) -> [fsTasks] 

  var fetchedTasks = [fsTasks]()

  fsGetTasks(documentID: categoryID, completation:  (tasks) in
    fetcheTasks = tasks
  )

  return fetchedTasks


我仍然只检索空数组。

【问题讨论】:

【参考方案1】:

这就是问题

func retrieveAllTasks(categoryID: String) -> [fsTasks] 
  var fetchedTasks = [fsTasks]()

  fsGetTasks(documentID: categoryID, completation:  (tasks) in
    fetcheTasks = tasks
  )

  return fetchedTasks

这也是一个异步函数(参见闭包),您必须给 Firebase 时间从服务器检索数据并在 Firebase 闭包中处理它。

这里发生的情况是,当您在 Firebase 闭包内执行此操作时,此闭包内不会发生这种情况。 return fetchedTasksfetchedTasks = tasks 之前返回。

我会直接调用 firebase 函数,因为它似乎不需要中间人 retrieveAllTasks 函数

self.fsGetTasks(documentID: "some_doc", completion:  taskArray in
    for task in taskArray 
       print(task
    
)

如果你这样做,你还需要添加一个@escaping 子句,而不是使用return fetchedTasks

【讨论】:

以上是关于SWIFTUI Firebase 检索子集合数据的主要内容,如果未能解决你的问题,请参考以下文章

不能使用 firebase 引用数据类型来获取子集合

Firebase 查询集合和合并子集合数据

Flutter Firebase云函数打字稿

Flutter Firebase 获取特定多个文档的子集合数据

如何将数据作为子集合添加到firebase颤振中的所有用户文档?

新的 Firebase Firestore DocumentDb 如何为大型子集合建模