使用 Firebase firestore 进行分页 - swift 4 [英] Pagination with Firebase firestore - swift 4

查看:18
本文介绍了使用 Firebase firestore 进行分页 - swift 4的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 firestore 对数据进行分页(无限滚动我的 tableview).我已尽最大努力集成了谷歌为分页提供的代码,但我仍然无法正确加载数据.

I'm trying to paginate data (infinitely scroll my tableview) using firestore. I've integrated the code google gives for pagination as best I can, but I'm still having problems getting the data to load in correctly.

初始数据集根据需要加载到 tableview 中.然后,当用户点击屏幕底部时,下一个x"个项目被加载.但是当用户第二次点击屏幕底部时,相同的x"个项目被简单地附加到表格中看法.相同的项目会无限期地添加.

The initial set of data loads into the tableview as wanted. Then, when the user hits the bottom of the screen, the next "x" amount of items are load in. But when the user hits the bottom of the screen the second time, the same "x" items are simply appended to the table view. The same items keep getting added indefinitely.

所以它是最初的 3 个ride"对象,然后是接下来的 4 个ride"对象,永远重复.

So its the initial 3 "ride" objects, followed by the next 4 "ride" objects repeating forever.

123 4567 4567 4567 4567...

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
            }

        })
    }
}

推荐答案

这就是我想出的解决方案!这个解决方案很可能会多次调用 firestore,为任何实际项目创建一个大帐单,但我猜你可以说它可以作为概念证明.

So here's the solution I've come up with! It is very likely that this solution makes multiple calls to firestore, creating a large bill for any real project, but it works as a proof of concept I guess you could say.

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

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

Here's how all the variables were initialized:

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

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

If you have any recommendations or edits, please feel free to share!

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
        }
    }
}

这篇关于使用 Firebase firestore 进行分页 - swift 4的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆