[英]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.