[英]How to read multiple custom objects from Firestore in Swift
使用 文档中的示例(对于 Swift)。 这是阅读多个文档的推荐方式:
db.collection("cities").whereField("capital", isEqualTo: true)
.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
}
}
}
这里推荐阅读自定义 object 的方法:
let docRef = db.collection("cities").document("BJ")
docRef.getDocument { (document, error) in
let result = Result {
try document.flatMap {
try $0.data(as: City.self)
}
}
switch result {
case .success(let city):
if let city = city {
print("City: \(city)")
} else {
print("Document does not exist")
}
case .failure(let error):
print("Error decoding city: \(error)")
}
}
没有读取多个自定义对象的示例。 这是我基于前两个示例的尝试:
db.collection("cities").whereField("capital", isEqualTo: true)
.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
if let snapshotDocuments = querySnapshot?.documents {
for document in snapshotDocuments {
let result = Result {
try document.flatMap { // error: Value of type 'QueryDocumentSnapshot' has no member 'flatMap'
try $0.data(as: City.self)
}
}
switch result {
case .success(let city):
if let city = city {
print("City: \(city)")
} else {
print("Document does not exist")
}
case .failure(let error):
print("Error decoding city: \(error)")
}
}
}
}
}
}
基于错误(我已将其内容放在上面代码中的注释中),我假设在查询单个 object 或多个时文档对象的类是不同的,即使它们通常的用途是相同的。 我应该如何更改加载多个自定义对象的代码以使其正常工作?
在第一个示例中,getDocument 返回一个 DocumentSnapshot,它是 DocumentSnapshot 的子集? 这是可选的,因此它可以与结果 object.flatmap 一起使用。
在第二个示例中,getDocuments 不返回 DocumentSnapshot,而是返回一个 QueryDocumentSnapshot:
QueryDocumentSnapshots 保证它们的内容总是非空的
所以这意味着它不是可选的,不能与 .flatmap 一起使用,因为它不能被解包。
Firebase 文档显示QueryDocumentSnapshot是 DocumentSnapshot 的子类,DocumentSnapshot 是可选的,QueryDocumentSnapshot 不是。
在这种情况下,.flatmap 被用来解开 DocumentSnapshot(一个可选的) - 发生的事情是 Result 中的 object 如果没有它,将是双重包装的可选。 So.flatmap 解开它一次,然后if let city = city {
再次解开它,所以它最终只是城市 object。
这就是我要做的......用这样的东西替换那个代码
func getCities() {
let docRef = db.collection("cities")
docRef.getDocuments { (querySnapshot, error) in
if let snapshotDocuments = querySnapshot?.documents {
for document in snapshotDocuments {
do {
if let city = try document.data(as: City.self) {
print(city.name)
}
} catch let error as NSError {
print("error: \(error.localizedDescription)")
}
}
}
}
}
编辑
我将从 github 借用这个,因为它使结果的使用(如文档中所示)更加清晰。
There are thus three cases to handle, which Swift lets us describe
nicely with built-in sum types:
Result
/\
Error Optional<City>
/\
Nil City //<- we get the actual city with `if let city = city {`
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.