guywitmanyhquestion
guywitmanyhquestion

Reputation: 33

Firestore Array Query More than 10 Elements (Pagination)

I'm trying to fetch all the guests of a party which is stored in an array called "PhoneNumbers." Each invite adds that persons phone number to the array. If there are more than 10 invites the app crashes because that is the Firestore limitation.

fileprivate func fetchGuests() {
        print("hi hi")
        guard !fetchedAllUsers, !fetchingMoreUsers else { return }
        fetchingMoreUsers = true
        tableView.reloadSections(IndexSet(integer: 1), with: .none)

        let partyUID = self.party?.partyUID ?? ""
        navigationItem.title = "\(party?.partyName ?? "") Guests"

        Firestore.firestore().collection("parties").document(partyUID).getDocument { (snap, err) in
            if let err = err {
                print(err, "fook")
            }
            guard let partyDict = snap?.data() else {return}
            let party = Party(dictionary: partyDict)

            self.phoneNumbers = party.guestPhoneNumbers as! [String]
            print(self.phoneNumbers)


        var query: Query
            if let lastFetchedNumber = self.lastFetchedNumber {
                query = Firestore.firestore().collection("users").whereField("PhoneNumber", in: self.phoneNumbers).order(by: "Full Name").start(after: [lastFetchedNumber]).limit(to: 9)

        } else {
            query = Firestore.firestore().collection("users").whereField("PhoneNumber", in: self.phoneNumbers).order(by: "Full Name").limit(to: 9)
        }

        // Change logic where gender variable is just the where field firebase thing
        query.getDocuments { (snapshot, err) in ......yadayadayada

Anyone have any ideas of how to work around the max 10 rule? Maybe should I add another array to the collection called PhoneNumbers2 for guests 9-18 and PhoneNumbers3 for 19-28?

Let me know if you have any ideas! (I can't add a new collection called guests because this app allows you to invite people you are not authenticated and I need to be able to query these numbers with out them having a UID if that makes sense)

Upvotes: 2

Views: 1574

Answers (3)

Manu Benjamin
Manu Benjamin

Reputation: 997

As per the firebase documentation it support up to 10 ids only in the where field, For querying more than 10 elements either we need to query each document individually or split array to chunks of 10 ids.

For querying each items individually. Check the code below,

let usersPromise = [];

usersIds.map((id) => {
    usersPromise.push(firestore.collection("users").doc(id).get());
});
        
Promise.all(usersPromise).then((docs) => {
    const users = docs.map((doc) => doc.data());
    
    // do your operations with users list
});

Upvotes: 0

Ranjithkumar
Ranjithkumar

Reputation: 18386

Step 1: Add array extension to get chunk of array

extension Array {
func chunked(into size: Int) -> [[Element]] {
    return stride(from: 0, to: count, by: size).map {
        Array(self[$0 ..< Swift.min($0 + size, count)])
    }
}
}

Step 2: Split your content to chunks

    let chunkedArray = ids.chunked(into: 10)

Step 3: Iterate chunk array and execute your firestore query

 chunkedArray.forEach
 { ids in

   let query = db.collection("TABLE_NAME").whereField("KEY_ID" , in: ids )
 //your firestore query request here 
 }

Upvotes: 2

Deji Toki
Deji Toki

Reputation: 31

I think you need to get rid of the "query = " part of it and just get documents directly in your if-else statement. This returned 17 documents in my test. I Used different collection names and field names but exact same structure .

Firestore.firestore().collection("users").whereField("PhoneNumber", in: array).order(by: "Full Name").getDocuments { (snapshot, error) in
        print(snapshot?.documents.count)
    }

Upvotes: 0

Related Questions