【问题标题】:SwiftUI Firestore query cursors pagination not workingSwiftUI Firestore 查询游标分页不起作用
【发布时间】:2020-04-30 18:33:35
【问题描述】:

我正在尝试在我的应用中实现分页。当应用程序加载时,我想加载第一项可以说。然后每次他单击刷新时都会加载一个新项目。 我已经在我的视图模型中实现了这个逻辑。

第一次在我的 SceneDelegate 中调用 homeViewModel.load()

let homeViewModel = HomeViewModel()
homeViewModel.refresh()

然后每次用户想要获取新日期时,我都会致电homeViewModel.refresh()

问题是,当应用加载时,我没有得到任何结果,当我点击刷新时,我不断地在表格中获取第二个文档。

我在这里做错了什么?

我的 HomeViewModel:

class HomeViewModel: ObservableObject, LoadProtocol {
    var firestoreService: FirestoreService = FirestoreService()
    @Published var items: [Item] = []
    let db = Firestore.firestore()
    var first: Query = Firestore.firestore().collection("items").limit(to: 1)
    
    load() {
        self.first.addSnapshotListener { (snapshot, error) in
            
            guard let snapshot = snapshot else {
                print("Error retrieving cities: \(error.debugDescription)")
                return
            }
            
            guard let lastSnapshot = snapshot.documents.last else {
                // The collection is empty.
                return
            }
            
            // Construct a new query starting after this document,
            // retrieving the next 25 cities.
            let next = self.db.collection("items")
                .start(afterDocument: lastSnapshot).limit(to: 1)
            
            self.first = next
            
            // Use the query for pagination.
        }
        
        
    }
    
    func refresh() {
        self.firestoreService.fetchCollection(query: self.first) { (result: Result<[Item], Error>) in
            switch result {
            case .success(let items):
                self.items += items
                self.addToCategories()
            case .failure(let error):
                print(error)
            }
        }
    }
}

【问题讨论】:

  • 嗯。这很可疑.limit(to: 1)
  • 它只是用于测试。可能是 20,但我没有那么多数据
  • 解决方案对您有用吗!?

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


【解决方案1】:

这是你的刷新功能

func refresh() {
    self.firestoreService.fetchCollection(query: self.first) { (result: Result<[Item], Error>) in
        switch result {
        case .success(let items):
            self.items += items
            self.addToCategories()
        case .failure(let error):
            print(error)
        }
    }
}

该函数中没有任何东西可以使光标进一步前进,因此它会一遍又一遍地读取相同的数据。

如果要读取下一组数据,每次刷新后需要将光标移动到最后一个文档,像这样

func refresh() {
    self.first.addSnapshotListener { (snapshot, error) in
        if let err = error {
            print(err.localizedDescription)
            return
        }

        guard let snapshot = snapshot else { return }

        guard let lastSnapshot = snapshot.documents.last else { return }

        let next = self.db.collection("items").start(afterDocument: lastSnapshot).limit(to: 2)

        self.first = next

        for doc in snapshot.documents {
            print(doc.documentID)
        }
    }
}

【讨论】:

  • 谢谢,那我需要去掉加载功能吗?并且只使用refresh()?
  • @RexhinHoxha 不一定,因为它提供了一个起点。但是,我经常发现在一个函数中完成所有操作是最容易维护的。查看我对 this question 的回答,因为它将所有内容整合到一个函数中 - 看看这是否会给你一些想法。使用我在此处发布的内容同样适用于加载和刷新。
  • 这很好,所以我们的想法是区分第一个查询和其余查询。第一个不应该有.start(afterDocument: lastSnapshot) 对吗?最后一件事。 addSnapshotListener 也会监听对这些文档所做的更改,对吗?
  • 这个.start(afterDocument: lastSnapshot) 在这种情况下实际上是可以的,因为它是在读入所有第一组文档之后发生的。它将刷新函数设置为从 self.first 开始,这将是在加载函数中读取的文档之后的文档。
  • 我根据您的其他问题对其进行了修改,并且工作正常!谢谢
猜你喜欢
  • 2020-01-15
  • 1970-01-01
  • 2018-12-28
  • 1970-01-01
  • 2021-11-28
  • 1970-01-01
  • 2018-03-18
  • 2020-07-27
  • 2021-04-12
相关资源
最近更新 更多