Skip to content Skip to sidebar Skip to footer

How To Paginate Firebase Query Which Contain Equalto() Api

I'm coding a shopping website with firebase. I have a some categories and subcategory in the sidebar, which onClick them, posts feeds should be updated accordingly, ordered by time

Solution 1:

Based on this source it looks like this functionality is not possible and is not going to be added. You can do something like this though

  1. Query your initial paging amount using equalTo
  2. Query by key ending at your last visible key and filter the results if the category matches the one you want then add it, otherwise ignore it.

I wrote my code in Swift3, but had the same issue maybe my code will be helpful to others.

staticfuncfilterTableByCategory(tableNumber: String, category: String) {
        filteringRef.child(tableNumber).queryOrdered(byChild: "category").queryEqual(toValue: category).queryLimited(toLast: 9).observeSingleEvent(of: .value, with: { snap inif snap.exists() {
                currentTablePosts.removeAll()
                for child in snap.children {
                    let child = child as?DataSnapshotiflet post = child?.value as? [String: AnyObject] {
                        let posst =Post()
                        iflet author = post["author"] as?String, let likes = post["likes"] as?Int, let pathToImage = post["pathToImage"] as?String, let postID = post["postID"] as?String, let postDescription = post["postDescription"] as?String, let timestamp = post["timestamp"] as?Double, let category = post["category"] as?String, let table = post["group"] as?String, let userID = post["userID"] as?String, let numberOfComments = post["numberOfComments"] as?Int, let region = post["region"] as?String {

                            posst.author = author
                            posst.likes = likes
                            posst.pathToImage = pathToImage
                            posst.postID = postID
                            posst.userID = userID
                            posst.fancyPostDescription =Helper.createAttributedString(author: author, postText: postDescription)
                            posst.postDescription = author +": "+ postDescription
                            posst.timestamp = timestamp
                            posst.table = table
                            posst.region = region
                            posst.category = category
                            posst.numberOfComments = numberOfComments
                            posst.userWhoPostedLabel =Helper.createAttributedPostLabel(username: author, table: table, region: region, category: category)

                            iflet people = post["peopleWhoLike"] as? [String: AnyObject] {
                                for(_, person) in people {
                                    posst.peopleWhoLike.append(person as!String)
                                }
                            }
                            currentTablePosts.insert(posst, at: 0)
                            NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTableCollectionView"), object: nil)
                        } // end of if let
                    }
                }
            }
            else {
                currentTablePosts.removeAll()
                NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTableCollectionView"), object: nil)
            }
        })
        filteringRef.removeAllObservers()
    }

    staticfuncgetMoreFilterByCategoryPosts(tableNumber: String, category: String, lastVisibleKey: String) {

        pagingReference.child(tableNumber).queryOrderedByKey().queryEnding(atValue: lastVisibleKey).queryLimited(toLast: 12).observeSingleEvent(of: .value, with: { snap inif snap.exists() {
                let currentNumberOfPosts = currentTablePosts.count
                for child in snap.children {
                    let child = child as?DataSnapshotiflet post = child?.value as? [String: AnyObject] {
                        iflet cat = post["category"] as?String, let postID = post["postID"] as?String {
                            if cat == category && postID != lastVisibleKey {
                                let posst =Post()
                                iflet author = post["author"] as?String, let likes = post["likes"] as?Int, let pathToImage = post["pathToImage"] as?String, let postDescription = post["postDescription"] as?String, let timestamp = post["timestamp"] as?Double, let table = post["group"] as?String, let userID = post["userID"] as?String, let numberOfComments = post["numberOfComments"] as?Int, let region = post["region"] as?String {

                                    posst.author = author
                                    posst.likes = likes
                                    posst.pathToImage = pathToImage
                                    posst.postID = postID
                                    posst.userID = userID
                                    posst.fancyPostDescription =Helper.createAttributedString(author: author, postText: postDescription)
                                    posst.postDescription = author +": "+ postDescription
                                    posst.timestamp = timestamp
                                    posst.table = table
                                    posst.region = region
                                    posst.category = cat
                                    posst.numberOfComments = numberOfComments
                                    posst.userWhoPostedLabel =Helper.createAttributedPostLabel(username: author, table: table, region: region, category: category)

                                    iflet people = post["peopleWhoLike"] as? [String: AnyObject] {
                                        for(_, person) in people {
                                            posst.peopleWhoLike.append(person as!String)
                                        }
                                    }
                                    currentTablePosts.insert(posst, at: currentNumberOfPosts)
                                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTableCollectionView"), object: nil)
                                } // end of if let
                            }
                        }
                    }
                }
            }
            else {
                print("snap == nil")
            }

        })
        pagingReference.removeAllObservers()

    }

Solution 2:

I ended up changing firebase realtime database schema.

I'm not sure but i think firebase intentionally doesn't release more apis. Its forcing you to double check your schema and improve it.

I have created a dedicated collection for categories and in the categories collection created separate node for each category. Its what firebase recommend to structure your database.

Then put each new post into the corresponding category.

So i can easily use OrderByKey() in each category and sub category and paginate them using startAt or endAt apis

An another solution would be using firebase function and elastic search. FlashLight package has been created for this purpose.

Post a Comment for "How To Paginate Firebase Query Which Contain Equalto() Api"