【问题标题】:Not able to paginate firestore filter based query无法对基于 Firestore 过滤器的查询进行分页
【发布时间】:2020-09-03 19:54:53
【问题描述】:

我正在尝试在 swift iOS 中实现分页,它使用基于类别的过滤器和 Firestore 作为后端。 但这仅在向下滚动时根据第一个查询加载到 5 个文档,并且不会加载更多文档,因为它应该在分页中发生。

此方法中使用的查询是基于类别类型的过滤器,过滤器的类型要么是获取所有文档,要么是基于选择的类别。当我使用过滤查询时,仅根据以下示例中的第二个查询加载两个文档

在 stopObserving() 函数中,它应该删除监听器。但是当查询被过滤,然后当过滤被删除时,它不会加载回未过滤的查询。

我只是无法分块加载数据。如果需要更多详细信息,请告诉我

问题的新增内容

当应用过滤器时,使用下面的代码,查询中存在 whereField() 子句,当过滤器被删除时,相同的子句也会从查询中删除,并且没有 whereField()查询分页中的 子句成功发生,否则查询中没有 whereField() 子句的分页

我也想要带有 whereField() 子句的分页,因为它在没有 whereField() 子句的情况下发生

代码

fileprivate func observeQuery() {

  fetchingMore = true
  guard var query = query else { return }
  stopObserving()

  if posts.isEmpty {
    query = query.limit(to: 5)

    print("First 6 rides loaded")
  } else {
    query = query.start(afterDocument: lastDocumentSnapshot).limit(to: 2)
  }

  listener = query.addSnapshotListener { [unowned self] (snapshot, error) in
    guard let snapshot = snapshot else {
      print("Error fetching snapshot results: \(error!)")
      return
    }
    let models = snapshot.documents.map { (document) -> Post in
      if let model = Post(dictionary: document.data()) {
        return model
      }
    }
    self.posts = models
    DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
      self.tableView.reloadData()
      self.fetchingMore = false
    })

    self.lastDocumentSnapshot = snapshot.documents.last

    self.documents = snapshot.documents

    if self.documents.count > 0 {
      self.tableView.backgroundView = nil
    } else {
      self.tableView.backgroundView = self.backgroundView
    }

  }
}

whereField() 查询的代码更新 BaseQuery,然后在 observeQuery() 中调用该查询以获取文档并对其进行分页

extension HomeViewController: FiltersViewControllerDelegate {

  func query(withCategory category: String?) -> Query {
    var filtered = baseQuery()

    if category == nil {
      stackViewHeightConstraint.constant = 0
      activeFiltersStackView.isHidden = true
    } else {
      stackViewHeightConstraint.constant = 44
      activeFiltersStackView.isHidden = false
    }

    // Advanced queries

    if let category = category, !category.isEmpty {
      filtered = filtered.whereField("category", isEqualTo: category)
    }

    return filtered
  }

  func controller(_ controller: FiltersViewController,
                  didSelectCategory category: String?
                  ) {
    let filtered = query(withCategory: category)

    if let category = category, !category.isEmpty {
      categoryFilterLabel.text = category
      categoryFilterLabel.isHidden = false
    } else {
      categoryFilterLabel.isHidden = true
    }

    self.query = filtered
    observeQuery()
  }

}

基本查询

fileprivate func baseQuery() -> Query {
  return Firestore.firestore().collection("collections").order(by: "timestamp", descending: true)
}

【问题讨论】:

  • 我没能完全理解你打算做什么以及你得到什么,你能详细说明一下吗?也看看the documentation,看看它是否对你有帮助。
  • @Ajordat 我在我的 tableview 中使用过滤器成功地从 firestore 获取文档,但直到现在我才能对数据进行分页。上面的代码不起作用,它只加载了部分数据。我试图在 tableview 中找到可以应用过滤器的分页解决方案,您可以检查 firestore 示例中的友好吃示例,我在这里应用的方法
  • 部分数据是什么意思?我假设您的意图是加载 5 个文档,并且每次分页加载 2 个,对吗?你目前得到什么?我一直在检查您提到的codelabresulting code,但我看不到那里正在执行分页。
  • @Ajordat 您对分页中文件的加载理解正确,这正是我想要的。目前,根据上述代码,最多只能从数据库中检索 5 个文档,并且不会执行进一步的数据加载。在codelabs的代码中没有执行分页,我想执行分页,上面的代码在应用过滤器时, where() 子句存在,当过滤器被删除时,相同的子句也从查询中删除,并且没有where子句的查询分页成功,否则没有where()子句的分页
  • 我知道您的 sn-p 在没有 where 条件时有效。但是你分享的代码没有where这个条件,是不是说明可以了?

标签: swift firebase google-cloud-firestore pagination


【解决方案1】:

在这种情况下的问题是您尝试按属性排序并在不同的属性上执行带有“等于”条件的where 子句。

如果你想执行这种操作,你必须为这两个属性创建一个composite index

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-14
    • 2021-10-19
    • 2020-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-31
    • 2018-09-07
    相关资源
    最近更新 更多