Декодирование вложенного объекта с помощью Swift и Firestore

#swift #firebase #google-cloud-firestore #codable #decodable

#swift #firebase #google-облако-firestore #кодируемый #декодируемый

Вопрос:

Я разрабатываю приложение с Swift 5 и Firestore. Я создал идентифицируемые и кодируемые структуры, и это работает хорошо, но у меня проблема с декодированием documentId для вложенных документов. Я не смог найти что-то подобное в Интернете. Я хотел бы знать, соответствует ли структура Firestore, которую я реализовал, моему варианту использования и как решить проблему с идентификатором.

Я должен показать список действий с некоторой информацией о пользователе и виде спорта (например, имя и изображение). Вот почему я пытаюсь вложить в объект Activity только ту информацию, которая мне нужна, чтобы не запрашивать всего пользователя и вид спорта для каждого действия в списке.

В Firestore:

Документ действия содержит:

 info (String)
organizer:
     - name (String)
     - image (String)
     - ref (Reference)
date (Date)
sport:
     - name (String)
     - image (String)
     - ref (Reference)
  

Вот мой код:

 import Foundation
import FirebaseFirestore
import FirebaseFirestoreSwift

struct User: Codable {
    @DocumentID var id: String? = UUID().uuidString
    
    let name: String
    let email: String?
    let image: String
    let birthday: Date?
    let description: String?
}

struct Sport: Codable {
    @DocumentID var id: String? = UUID().uuidString
    
    let name: String
    let image: String
}

struct Activity: Codable {
    @DocumentID var id: String? = UUID().uuidString
    
    let organizer: User
    let info: String
    let date: Date
    let sport: Sport

    static func getActivities(completion: @escaping (_ activities: [Activity]?) -> Void) {
        Activity.collectionReference.getDocuments { (querySnapshot, error) in
            guard error == nil else {
                print("Error: (error?.localizedDescription ?? "Generic error")")
                return
            }
            
            let activities = querySnapshot?.documents.compactMap({ (queryDocumentSnapshot) -> Activity? in
                
                return try! queryDocumentSnapshot.data(as: Activity.self)
            })
            
            completion(activities)
        }
    }
}
  

Вызывая Activity.getActivities, я могу получить все, что мне нужно, но при декодировании user и sport непосредственно из объекта activity они получают идентификатор activity вместо своего собственного. Это неправильно, потому что таким образом у меня неправильная ссылка на объект. Идея состоит в том, чтобы сохранить ссылку, чтобы использовать ее на странице сведений и получить полный объект.
Может ли кто-нибудь сказать мне, как лучше всего структурировать такую архитектуру?
Заранее благодарю вас.

Комментарии:

1. Вы уверены, что хотите интегрировать сетевые операции в модель объекта, который извлекается сетевой операцией? Для меня это сомнительно.

2. Нет, именно поэтому я предпочитаю дублировать некоторые пользовательские данные в модели активности. Таким образом, я могу просто сохранить ссылку на пользователя при извлечении действия и вызвать пользователя в отдельном вызове.

3. Я имею в виду, что я бы пересмотрел стратегию включения сетевых операций в саму модель. Модель, IMO, должна быть зарезервирована для хранения данных, а не для хранения и извлечения данных. Задача извлечения данных должна быть возложена на другой объект.

4. О, извините. Спасибо за совет, я просто тестирую наилучший способ структурирования приложения с помощью Firestore. Я последую вашему совету!