如何从 firestore 获取身份证文件?
现在,我从后端获得了多个 ID文档,并且我需要在 tableview 中显示收到的ID文档。
在 firestore 中,我有以下 ids :
xNlguCptKllobZ9XD5m1
uKDbeWxn9llz52WbWj37
82s6W3so0RAKPZFzGyl6
EF6jhVgDr52MhOILAAwf
FXtsMKOTvlVhJjVCBFj8
JtThFuT4qoK4TWJGtr3n
TL1fOBgIlX5C7qcSShGu
UkZq3Uul5etclKepRjJF
aGzLEsEGjNA9nwc4VudD
dZp0qITGVlYUCFw0dS8C
n0zizZzw7WTLpXxcZNC6
例如,我的后端仅发现以下 id :
JtThFuT4qoK4TWJGtr3n
TL1fOBgIlX5C7qcSShGu
UkZq3Uul5etclKepRjJF
或
aGzLEsEGjNA9nwc4VudD
dZp0qITGVlYUCFw0dS8C
n0zizZzw7WTLpXxcZNC6
我只需要在 tableview 中显示这三个ID。 (但实际上,后端向我返回了100多个ID,在下面,您会看到疯狂地对这些ID进行排序)
后端将此ID附加到临时数组var tempIds: [String] = []
那么我如何只能从 firestore 获取这些ID,并在 tableview 中显示它们?
我使用以下代码:
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
}
}
}
我需要在后台处理来自后端的ID,并且处理后需要在 tableview 中显示已处理的ID,而无需进行疯狂的排序。
可能需要使用addSnapshotListened
,但我不知道如何使用。
更新的代码:
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()
}
})
答案 0 :(得分:1)
与其一一获取文档, 您可以使用“IN”查询通过 1 个请求获取 10 个文档:
userCollection.where('uid', 'in', ["1231","222","2131"]);
// or
myCollection.where(firestore.FieldPath.documentId(), 'in', ["123","456","789"]);
Firestore 文档: “使用 in 运算符将同一字段上最多 10 个相等 (==) 子句与逻辑 OR 组合在一起。in 查询返回给定字段与任何比较值匹配的文档”
答案 1 :(得分:0)
在需要单个文档时,应保留通过其标识符IMO获取文档的时间。如果需要提取多个文档,则IMO应该构造一个查询。请记住,存储现在是数据库中最便宜的组件(因为您使用的是NoSQL)。它曾经是最昂贵的,这就是为什么SQL这么长时间占据主导地位的原因。因此,要充分利用NoSQL,您应该对数据库中的foo进行非规范化,这在Firestore中表示要满足所有查询的需要进行尽可能多的收集(以便每个查询返回最少的文档),甚至如果这些集合存储其他集合中其他文档中已经存在的数据。与其他费用相比,您在Firestore中存储的数据的实际成本应为美金。
因此,如果我是您,我将在这些文档中添加一个可以查询的字段,或者创建一个仅存储此查询所需字段的新集合(可以查询的字段)。但是,如果不可能,并且您仍然想按标识符来获取多个文档,则需要进行n个单独的get document请求,并使用一个调度组来处理它们的异步返回:
let docIds = ["JtThFuT4qoK4TWJGtr3n", "TL1fOBgIlX5C7qcSShGu", "UkZq3Uul5etclKepRjJF"]
let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
for id in docIds {
Firestore.firestore().collection(...).document(id).getDocument{ (document, error) in
// append to array
dispatchGroup.leave()
}
}
dispatchGroup.notify(queue: .global(qos: .default), execute: {
// hand off to another array if this table is ever refreshed on the fly
DispatchQueue.main.async {
// reload table
}
})
答案 2 :(得分:0)
我也面临同样的任务。没有更好的解决方案。一张一张地获取文档,所以我写了一个小扩展名:
extension CollectionReference {
typealias MultiDocumentFetchCompletion = ([String: Result<[String: Any], Error>]) -> Void
class func fetchDocuments(with ids: [String], in collection: CollectionReference, completion:@escaping MultiDocumentFetchCompletion) -> Bool {
guard ids.count > 0, ids.count <= 50 else { return false }
var results = [String: Result<[String: Any], Error>]()
for documentId in ids {
collection.document(documentId).getDocument(completion: { (documentSnapshot, error) in
if let documentData = documentSnapshot?.data() {
results[documentId] = .success(documentData)
} else {
results[documentId] = .failure(NSError(domain: "FIRCollectionReference", code: 0, userInfo: nil))
}
if results.count == ids.count {
completion(results)
}
})
}
return true
}
}