簡體   English   中英

如何從 Swift 中的 Firestore 讀取多個自定義對象

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM