How can I get ids documents from firestore?
Now I get several ids documents from backend and me need display received ids documents in tableview.
In firestore i have this ids:
xNlguCptKllobZ9XD5m1
uKDbeWxn9llz52WbWj37
82s6W3so0RAKPZFzGyl6
EF6jhVgDr52MhOILAAwf
FXtsMKOTvlVhJjVCBFj8
JtThFuT4qoK4TWJGtr3n
TL1fOBgIlX5C7qcSShGu
UkZq3Uul5etclKepRjJF
aGzLEsEGjNA9nwc4VudD
dZp0qITGVlYUCFw0dS8C
n0zizZzw7WTLpXxcZNC6
And for example my backend found only this ids:
JtThFuT4qoK4TWJGtr3n
TL1fOBgIlX5C7qcSShGu
UkZq3Uul5etclKepRjJF
or
aGzLEsEGjNA9nwc4VudD
dZp0qITGVlYUCFw0dS8C
n0zizZzw7WTLpXxcZNC6
Me need display only this three ids in tableview. (But in reality backend return me 100+ ids and below you can see frantic sorting these ids)
Backend append this ids in temporary array var tempIds: [String] = []
So how I can get from firestore only those ids and display their in tableview?
I use this code:
fileprivate func query(ids: String) {
Firestore.firestore().collection(...).document(ids).getDocument{ (document, error) in
if let doc = document, doc.exists {
if let newModel = Halls(dictionary: doc.data()!, id: doc.documentID) {
self.halls.append(newModel)
self.halls.shuffle()
self.halls.sort(by: { $0.priority > $1.priority })
self.tableView.reloadData()
} else {
fatalError("Fatal error")
}
} else {
return
}
}
}
Me need to process ids from backend in background and after process need to show processed ids in tableview without frantic sorting.
May be need use addSnapshotListened
, but I don't understand how.
UPDATED CODE:
for id in idsList {
dispatchGroup.enter()
Firestore.firestore().collection(...).document(id).getDocument{ (document, error) in
if let doc = document, doc.exists {
if let newHallModel = Halls(dictionary: doc.data()!, id: doc.documentID) {
self.tempHalls.append(newHallModel)
dispatchGroup.leave()
} else {
fatalError("Fatal error")
}
} else {
print("Document does not exist")
MBProgressHUD.hide(for: self.view, animated: true)
return
}
}
}
dispatchGroup.notify(queue: .global(qos: .default), execute: {
self.halls = self.tempHalls
DispatchQueue.main.async {
MBProgressHUD.hide(for: self.view, animated: true)
self.tableView.reloadData()
}
})
Getting a document by its identifier should be used when you need a single document or documents you cannot query for. Don't be hesitant to denormalize your data to make queries work, that's the point of NoSQL. If I were you, I'd either add a field to these documents so that they can be queried or denormalize this dataset set with a new collection (just for this query). However, if you still choose to fetch multiple documents by identifier, then you need to make n
getDocument
requests and use a dispatch group to handle their synchronization.
let docIds = ["JtThFuT4qoK4TWJGtr3n", "TL1fOBgIlX5C7qcSShGu", "UkZq3Uul5etclKepRjJF"]
let d = DispatchGroup()
for id in docIds {
d.enter()
Firestore.firestore().collection(...).document(id).getDocument { (document, error) in
// handle doc
d.leave() // always leave no matter how you exit this closure
}
}
d.notify(queue: .main, execute: {
// here is your completion when the last leave() was called
})
All the dispatch group does is keep a count of the number of times it's entered and left and when they match, it calls its notify(queue:execute:)
method (its completion handler).