swift - 有没有更好的方法来优化这个 Firestore 查询?

标签 swift firebase google-cloud-firestore

现在我根据另一个字符串数组查询 Firestore 数组。这工作正常,但我想知道这是否正确以及是否有优化它以使其更快的方法。

这是我的代码。

var exampleArray = [test]()

func loadData(textArray : [String]){
        let db = Firestore.firestore()

        for i in 0..<textArray.count{
            db.collection("testCollection").whereField("testField", arrayContains: textArray[i]).getDocuments{ (querySnapshot, err) in
                if let err = err {
                    print("\(err.localizedDescription)")
                    print("Test Error")
                } else {
                    if (querySnapshot!.isEmpty == false){
                        let res = querySnapshot!.documents.compactMap({test(dictionary: $0.data())})
                        self.exampleArray.append(contentsOf: res)
                        self.summaryTableView.reloadData()
                        SVProgressHUD.dismiss()
                        print(self.textArray[i])

                    }
                }
            }
        }
    }

提前致谢。

更新:

一些信息:

  • 目前,VisionCloud 识别过程和查询大约需要 10-11 秒。 7 秒识别和 3-4 秒查询。
  • 数据库有 7700 个文档,每个文档有 7 个字段。

基本上我的应用会执行以下操作:

  • 用户拍照
  • 使用 OCR,图像变成文本,我将文本附加到字符串数组中。我们不知道将有多少个字符串。可能是 0 也可能是 50。
  • 然后我根据字符串数组查询 Firestore 数组。

最佳答案

正如评论中所指出的,您在一个循环中运行一堆异步请求(这总是很糟糕)并且您在每个请求解析时重新加载数据导致 tableView 保持用新数据重新绘制。

您要做的是将所有这些数据库请求添加到 DispatchGroup。当他们解决时,将数据添加到您的数组中。一旦他们都完成了,执行一个 tableView.reloadData() 并关闭你的 SVProgressHud

这不仅可以加快处理速度,因为多个调用可以并行发生,而且您的用户不会在添加新数据和 tableView 快速重新加载 X 次时弹跳表格行火。

编辑:您要求提供示例 - 这是非常快速的,并且是在 SO 上编写的,因此请查找 XCode 以通知您任何拼写错误或错误。

class MyVC: UIViewController {

  var exampleArray = [test]()
  let db = Firestore.firestore()
  let dispatchGroup = DispatchGroup()

  override func viewDidLoad(animated: bool) {
    super.viewDidLoad(animated)

    myTableView.delegate = self
    myTableView.dataSource = self

    for i in 0..<textArray.count {
      getTestFieldRecords(i)
    }

    dispatchGroup.notify(queue: .main) {
      self.myTableView.reloadData()
    }
  }

  private func getTestFieldRecords(_ record: Int) {
    dispatchGroup.enter()
    db.collection("testCollection").whereField("testField", arrayContains: textArray[i]).getDocuments{ (querySnapshot, err) in
      if let err = err {
        print("\(err.localizedDescription)")
        print("Test Error")
      } else {
        // rest of your code because I'm too lazy to format it
      }
      self.dispatchGroup.leave()
    }
  }

}

确保每次都调用 leave()——不管是否出错。在所有 enter() 命令都用 leave() 命令完成之前,DispatchGroup 不会完成。希望这可以帮助您指明正确的方向!

关于swift - 有没有更好的方法来优化这个 Firestore 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56534244/

相关文章:

php - 使用 file_get_contents 将数据从 Swift 传递到 PHP for JSON?

swift - swift 中的 Curried 中缀运算符。可能吗?

ios - uitableviewcell 背景颜色上的快速更改标签

reactjs - 如何使用 React Redux 实现 Firebase 身份验证?

javascript - 如何修复vuejs中的 "ReferenceError: require is not defined"

kotlin - 如何将自动生成的ID添加到Cloud Firestore数据库

ios - 使用 UIActivityViewController 未将多个图像保存在照片库中

javascript - 为什么 Privacy Badger 会阻止 Firebase javascript 文件?

java - 如何在事务内将文档添加到 Firebase 集合?

google-cloud-firestore - 云 Composer : "PERMISSION_DENIED: The caller does not have permission"