Reputation: 33
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
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
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
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