Пользовательский объект Swift Firebase с идентификатором документа - PullRequest
0 голосов
/ 23 апреля 2020

Есть ли способ создать пользовательский объект Swift, в котором я назначаю идентификатор документа Firebase параметру объекта?

Код взят отсюда: 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 и создание объекта. Код также взят из ссылки 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)")
    }
}
}```

Ответы [ 2 ]

2 голосов
/ 23 апреля 2020

Код в вопросе берет информацию из документа и сопоставляет ее с городским объектом. Если вы хотите присвоить documentId этому объекту города, это будет сделано

switch result {
case .success(let city):
    if var city = city {
        city.docId = document!.documentID
        print("City: \(city)")
    } else {
        print("Document does not exist")
    }
case .failure(let error):
    print("Error decoding city: \(error)")
}

Note var city, чтобы вы могли затем присвоить ему documentID с помощью

city.docId = document!.documentID  //please safely unwrap optionals (!)

и надеть забудь это

public struct City: Codable {
   var docId = ""    //needs to be a var
   let name: String
0 голосов
/ 25 апреля 2020

Существует еще более простой способ добиться этого с помощью поддержки Codable, которую мы недавно добавили в Firestore:

Добавьте модуль FirebaseFirestoreSwift:

# 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. Также обратите внимание, что - поскольку структура 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)
      }
    }
  }
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...