【问题标题】:SWIFT Firebase Realtime Database pagination double fetch issueSWIFT Firebase 实时数据库分页双重提取问题
【发布时间】:2021-07-04 20:40:54
【问题描述】:

当我使用以下分页方法时,有时我会获取双重结果,有时分页不起作用。我想知道问题是什么以及 Firebase 实时数据库分页的最佳实践是什么。

我的用户数据结构:

"users" 
|- autoId1
     |- name: "abc"
     |- age: "22"
     |- ...
|- autoId2
     |- name: "xyz"
     |- age: "29"
     |- ...
|- autoId3
     |- name: "bbb"
     |- age: "20"
     |- ...

我有一个班级的集合,每个班级都有学生人数:

"class"
   |- "autoId" //this is the autoId for class
     |- autoId1: 1  //these are students autoId
     |- autoId2: 1
     |- autoId3: 1

当我在课堂上获取学生时,我有以下代码:

private var currentKey = nil
private func fetchUsersAtClass() {
    guard let currentUid = Auth.auth().currentUser?.uid else {return}
    if currentKey == nil {
          //classId is the autoId for a class
        CLASS_USERS.child(classId).queryLimited(toLast: 5).observeSingleEvent(of: .value) { (snapshot) in
         guard let first = snapshot.children.allObjects.first as? DataSnapshot else {return}
         guard let allObjects = snapshot.children.allObjects as? [DataSnapshot] else {return}
            allObjects.forEach({ (snapshot) in
                let uid = snapshot.key
               //fetch users from the users collection based on the [userId] fetched from class collection
                Database.fetchUser(with: uid, completion: { (user) in
                    self.users.append(user)
                    self.users.sort(by: { (p1, p2) -> Bool in
                        return p1.credit > p2.credit
                    })
                    self.tableView.reloadData()
                })
            })
            self.currentKey = first.key
        }
    } else {
        CLASS_USERS.child(classId).queryOrderedByKey().queryEnding(atValue: currentKey).queryLimited(toLast: 4).observeSingleEvent(of: .value, with: { (snapshot) in
            guard let first = snapshot.children.allObjects.first as? DataSnapshot else { return }
            guard let allObjects = snapshot.children.allObjects as? [DataSnapshot] else { return }
            
            allObjects.forEach({ (snapshot) in
                let uid = snapshot.key
                if uid != self.currentKey {
                    Database.fetchUser(with: uid, completion: { (user) in
                        self.users.append(user)
                        self.users.sort(by: { (p1, p2) -> Bool in
                            return p1.credit > p2.credit
                        })
                        self.tableView.reloadData()
                    })
                }
            })
            self.currentKey = first.key
        })
    }
}

对于触发分页,我有:

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        if users.count > 4 {
            if indexPath.item == users.count - 1 {
                fetchUsersAtClass()
            }
        } 
}

【问题讨论】:

  • 一个叫 'usersBiz' 的人是从哪里来的?
  • 我已经更正了。应该是用户

标签: swift firebase firebase-realtime-database pagination


【解决方案1】:

由于您使用的是.queryOrderedByKey().queryEnding(atValue: currentKey),因此实际上预期带有currentKey 的节点会同时针对前一页和当前页进行检索。您必须在应用程序代码中删除它。

最近向 API 添加了一个新的 queryEnding(beforeValue:) 方法,它允许您不获取重叠条目。

【讨论】:

  • 谢谢。我会试试 queryEnding(beforeValue:)
  • 我浏览了文档,今晚我会搜索 GitHub 并试一试。如果它有效,我肯定会支持你的帖子
  • 你在 GitHub 上碰巧知道一些使用这种方法的例子吗?
  • 它的工作原理与queryEnding(atValue:) 完全相同,但不会返回带有您传入的密钥的节点。
  • 当我使用它时,调用中的参数标签不正确(有'beforeValue:',预期的'atValue:')。我已将我的 firebase 更新到最新版本
猜你喜欢
  • 2022-10-14
  • 2020-07-07
  • 2021-10-12
  • 1970-01-01
  • 2018-09-13
  • 1970-01-01
  • 2021-07-01
  • 2021-04-09
相关资源
最近更新 更多