获取多个Firestore ID文件

时间:2019-04-22 14:58:04

标签: ios swift firebase document

如何从 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()
                            }
                        })

enter image description here

3 个答案:

答案 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
}
}