与Firebase firestore的分页 - 快速4

问题描述 投票:1回答:1

我正在尝试使用firestore对数据进行分页(无限滚动我的tableview)。我尽可能地集成了谷歌提供的代码用于分页,但是我仍然无法正确加载数据。

初始数据集按需要加载到tableview中。然后,当用户点击屏幕的底部时,下一个“x”项目的数量将被加载。但是当用户第二次点击屏幕的底部时,相同的“x”项目将被简单地附加到表格中视图。相同的项目会无限期地添加。

因此它最初的3个“骑行”物体,接着是下一个4个“骑行”物体永远重复。

123 4567 4567 4567 4567...

如何正确加载数据?

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let offsetY = scrollView.contentOffset.y
    let contentHeight = scrollView.contentSize.height

    if offsetY > contentHeight - scrollView.frame.height {
        // Bottom of the screen is reached
        if !fetchingMore {
            beginBatchFetch()
        }
    }
}

func beginBatchFetch() {
    // Array containing "Ride" objcets is "rides"

    fetchingMore = true

    // Database reference to "rides" collection
    let ridesRef = db.collection("rides")

    let first = ridesRef.limit(to: 3)

    first.addSnapshotListener { (snapshot, err) in
        if let snapshot = snapshot {
            // Snapshot isn't nil
            if self.rides.isEmpty {
                // rides array is empty (initial data needs to be loaded in).
                let initialRides = snapshot.documents.compactMap({Ride(dictionary: $0.data())})
                self.rides.append(contentsOf: initialRides)
                self.fetchingMore = false
                DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: {
                    self.tableView.reloadData()
                })
                print("first rides loaded in")
            }
        } else {
            // Error
            print("Error retreiving rides: \(err.debugDescription)")
            return
        }

        // reference to lastSnapshot
        guard let lastSnapshot = snapshot!.documents.last else{
            // The collection is empty
            return
        }


        let next = ridesRef.limit(to: 4).start(afterDocument: lastSnapshot)

        next.addSnapshotListener({ (snapshot, err) in
            if let snapshot = snapshot {

                if !self.rides.isEmpty {

                    let newRides = snapshot.documents.compactMap({Ride(dictionary: $0.data())})
                    self.rides.append(contentsOf: newRides)
                    self.fetchingMore = false
                    DispatchQueue.main.asyncAfter(deadline: .now() + 7, execute: {
                        self.tableView.reloadData()
                    })

                    print("new items")
                    return
                }
            } else {
                print("Error retreiving rides: \(err.debugDescription)")
                return
            }

        })
    }
}
swift firebase pagination google-cloud-firestore infinite-scroll
1个回答
8
投票

所以这是我提出的解决方案!这个解决方案很可能会对firestore进行多次调用,为任何真实的项目创建大额账单,但它可以作为概念证明,我想你可以说。

如果您有任何建议或编辑,请随时分享!

以下是所有变量的初始化方式:

var rides = [Ride]()
var lastDocumentSnapshot: DocumentSnapshot!
var fetchingMore = false

如果您有任何建议或编辑,请随时分享!

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let offsetY = scrollView.contentOffset.y
    let contentHeight = scrollView.contentSize.height
    //print("offsetY: \(offsetY) | contHeight-scrollViewHeight: \(contentHeight-scrollView.frame.height)")
    if offsetY > contentHeight - scrollView.frame.height - 50 {
        // Bottom of the screen is reached
        if !fetchingMore {
            paginateData()
        }
    }
}

// Paginates data
func paginateData() {

    fetchingMore = true

    var query: Query!

    if rides.isEmpty {
        query = db.collection("rides").order(by: "price").limit(to: 6)
        print("First 6 rides loaded")
    } else {
        query = db.collection("rides").order(by: "price").start(afterDocument: lastDocumentSnapshot).limit(to: 4)
        print("Next 4 rides loaded")
    }

    query.getDocuments { (snapshot, err) in
        if let err = err {
            print("\(err.localizedDescription)")
        } else if snapshot!.isEmpty {
            self.fetchingMore = false
            return
        } else {
            let newRides = snapshot!.documents.compactMap({Ride(dictionary: $0.data())})
            self.rides.append(contentsOf: newRides)

            //
            DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
                self.tableView.reloadData()
                self.fetchingMore = false
            })

            self.lastDocumentSnapshot = snapshot!.documents.last
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.