【问题标题】:Storing asynchronous Cloud Firestore query results in Swift在 Swift 中存储异步 Cloud Firestore 查询结果
【发布时间】:2020-04-16 08:35:22
【问题描述】:

我正在开发一个使用 Swift 5、SwiftUI 和 Firebase 的简单项目,该项目循环遍历数组中的给定 id,在 Cloud Firestore 数据库中搜索每个 id,并将与 id 关联的相应名称附加到新数组中。

这是我的数据库的图片:

例如,给我一个数组几个 id,然后对于给定数组中的每个元素,我获取与该 id 关联的文档,然后打印该文档中的“firstname”字段。

但是,我想将检索到的每个“名字”值存储到本地单独的数组中以供以后使用。在 Javascript 中,我知道这是使用 await 和 async 函数完成的,但我通过无数小时的 Swift 没有 async 或 await 的故障排除。

这是我的代码:

func convertToNames(arr: [String]) -> [String]{

    var newArr : [String] = []

      for id in arr {
         let docRef = db.collection("users").document(id)
                 docRef.getDocument { (document, error) in
                     if let document = document, document.exists {
                         let dataDescription = document.data().map(String.init(describing:)) ?? "nil"
                         let data = document.get("firstname") ?? "nil"

                         print("gotten data: \(data)")
                         newArr.append(String(describing: data))

                     } else {
                         print("Document does not exist")
                     }
            }
        }

    print("NEW ARRAY: \(newArr)")
    return (newArr)
}

这段代码在完成时会打印一个空数组,我明白为什么,但我不知道如何让它在 Swift 中工作。我今天花了大约 5 个小时来筛选 Firebase 文档、查看示例代码并筛选 Youtube,但没有一个资源能够在我需要的范围内解决这个问题。如果无法做到,请告诉我。

【问题讨论】:

  • getDocument 是异步的并立即返回。数据在回调中可用,一段时间后。您需要为 swift 采用异步编程技术,这意味着您的函数将无法仅返回 String。 stackoverflow.com/questions/25203556/…

标签: ios swift firebase asynchronous google-cloud-firestore


【解决方案1】:

除了完成之外,您还需要一个调度组

func convertToNames(arr: [String],completion:@escaping(([String]) -> ())) {

    var newArr : [String] = []
    let g = DispatchGroup()
      for id in arr {
         let docRef = db.collection("users").document(id) 
                 g.enter()
                 docRef.getDocument { (document, error) in
                     if let document = document, document.exists {
                         let dataDescription = document.data().map(String.init(describing:)) ?? "nil"
                         let data = document.get("firstname") ?? "nil"

                         print("gotten data: \(data)")
                         newArr.append(String(describing: data))
                         g.leave()
                     } else {
                         print("Document does not exist")
                         g.leave()
                     }
            }
        }

       g.notify(queue:.main) { 
         print("NEW ARRAY: \(newArr)")
         completion(newArr)
       }
}

打电话

convertToNames(arr:<#arr#>) { res in
     print(res)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-19
    • 2020-06-01
    • 1970-01-01
    • 2011-08-14
    • 2018-05-10
    • 2021-02-04
    相关资源
    最近更新 更多