带有文档 ID 的 Swift Firebase 自定义对象

Sim*_*mon 3 firebase swift swiftui

有没有办法创建自定义 Swift 对象,将 Firebase 文档 ID 分配给对象参数?

代码取自此处: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
    }
}
Run Code Online (Sandbox Code Playgroud)

获取 Firebase 文档并创建对象。代码也取自上面的 Goolge Firebase 链接。

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)")
    }
}
}```
Run Code Online (Sandbox Code Playgroud)

Pet*_*ese 12

有一种更简单的方法可以使用我们最近添加到 Firestore 的 Codable 支持来实现此目的:

添加FirebaseFirestoreSwiftPod:

# 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
Run Code Online (Sandbox Code Playgroud)
# 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
Run Code Online (Sandbox Code Playgroud)

通过使用@DocumentID属性包装器,您可以告诉 Firestore 的 Codable 支持您希望它将文档的 ID 映射到字段id。另请注意,随着City结构的实现Identifiable,您将能够在 SwiftUI 中使用它ListView

然后,在视图模型中,使用queryDocumentSnapshot.data(as:)类型安全的方式获取和映射数据:

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)
      }
    }
  }
}

Run Code Online (Sandbox Code Playgroud)

  • 我试图弄清楚当我的模型(出于架构原因)需要成为一个类时如何使用 @DocumentID。我一直把 Id 返回为零。有人遇到过这种情况吗? (2认同)