带有文档 ID 的 Swift Firebase 自定义对象 [英] Swift Firebase Custom Object with Document ID
问题描述
有没有办法创建一个自定义的 Swift 对象,我可以在其中将 Firebase 文档 ID 分配给一个对象参数?
Is there a way to create a custom Swift Object where I assign the Firebase Document ID to a Object parameter?
代码取自此处:https://firebase.google.com/docs/firestore/query-data/get-data#custom_objects
public struct City: Codable {
let id: String // here I'd like to fill in the Document ID
let name: String?
let state: String?
let country: String?
let isCapital: Bool?
let population: Int64?
enum CodingKeys: String, CodingKey {
case id = //Document ID
case name
case state
case country
case isCapital
case population
}
}
获取 Firebase 文档并创建对象.代码也取自上面的 Google Firebase 链接.
Getting Firebase document and creating the Object. Code also taken from Goolge Firebase link above.
fun getObject(){
let db = Firestore.firestore()
let docRef = db.collection("cities").document("BJ")
docRef.getDocument { (document, error) in
if let error = error {
print("Error retrieving document: \(error)")
return
}
let result = Result {
try document?.data(as: City.self)
}
switch result {
case .success(let city):
if let city = city {
// A `City` value was successfully initialized from the DocumentSnapshot.
print("City: \(city)")
} else {
// A nil value was successfully initialized from the DocumentSnapshot,
// or the DocumentSnapshot was nil.
print("Document does not exist")
}
case .failure(let error):
// A `City` value could not be initialized from the DocumentSnapshot.
print("Error decoding city: \(error)")
}
}
}```
推荐答案
使用我们最近添加到 Firestore 的 Codable 支持,有一种更简单的方法可以实现此目的:
There is an even easier way to achieve this using the Codable support we added to Firestore recently:
添加 FirebaseFirestoreSwift
pod:
# Uncomment the next line to define a global platform for your project
platform :ios, '13.0'
target 'MyAwesomeApp' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# Pods for MyAwesomeApp
pod 'Firebase/Analytics'
pod 'Firebase/Firestore'
pod 'FirebaseFirestoreSwift'
end
import FirebaseFirestoreSwift
struct City: Codable, Identifiable {
@DocumentID var id: String? = UUID().uuidString
let name: String
let state: String
let country: String
let isCapital: Bool
let population: Int64
// you only need CodingKeys if your attribute names in Firestore differ from the property names on your struct!
}
通过使用 @DocumentID
属性包装器,您告诉 Firestore 的 Codable 支持,您希望它将文档的 ID 映射到 id
字段.另请注意 - 由于 City
结构实现了 Identifiable
- 您将能够在 SwiftUI ListView
中使用它.
By using the @DocumentID
property wrapper, you tell Firestore's Codable support that you want it to map the document's ID to the id
field. Also note that - as the City
struct implements Identifiable
- you will be able to use it in a SwiftUI ListView
.
然后,在您的视图模型中,使用 queryDocumentSnapshot.data(as:)
以类型安全的方式获取和映射数据:
Then, in your view model, use queryDocumentSnapshot.data(as:)
to fetch and map data in a typesafe way:
import FirebaseFirestore
class CitiesViewModel: ObservableObject {
@Published var cities = [City]()
private var db = Firestore.firestore()
private var listenerRegistration: ListenerRegistration?
deinit {
unregister()
}
func unregister() {
if listenerRegistration != nil {
listenerRegistration?.remove()
}
}
func fetchData() {
unregister()
listenerRegistration = db.collection("cities").addSnapshotListener { (querySnapshot, error) in
guard let documents = querySnapshot?.documents else {
print("No documents")
return
}
self.cities = documents.compactMap { queryDocumentSnapshot -> City? in
return try? queryDocumentSnapshot.data(as: City.self)
}
}
}
}
这篇关于带有文档 ID 的 Swift Firebase 自定义对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!