Получение идентификатора документа при декодировании структуры Firestore с помощью пользовательского декодируемого

# #swift #firebase #google-cloud-firestore

Вопрос:

У меня есть следующая структура

 struct Vehicle: Codable, Identifiable {
    @DocumentID var id: String?
    var name: String
}
 

Пока я использую декодер Swift по умолчанию, я могу загружать записи Firestore без каких-либо проблем (с использованием document.data(as: ) и id содержать идентификатор документа.

Однако теперь мне нужна пользовательская функция декодирования внутри этой структуры, и именно здесь все идет не так.

Я могу загрузить все поля без каких-либо проблем, но идентификатор документа не заполнен.

Я пытался вот так:

     init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
    
        if let id = try container.decodeIfPresent(DocumentID<String>.self, forKey: .id) {
            self.id = id.wrappedValue
        }

 

Но это дает мне nil .

Я нашел несколько других ответов, но они говорят о DocumentReference том, какой тип не (или больше нет?) существовать.

Как я могу это решить?

Спасибо

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

1. У меня нет способа проверить, но посмотрите, работает ли следующее: self._id = container.decode(DocumentID<String>.self, forKey: .id) . (Я предполагаю, что у вас все @DocumentID var id: String? еще есть)

2. Но это именно то, что я сделал? 🙂

Ответ №1:

Чтобы уточнить, a DocumentReference -это объект, который содержит путь к документу firestore, и это объект, который вы бы назвали эквивалентом своих платформ .get() для извлечения данных через a DocumentSnapshot . Я не очень хорошо знаком со swift, но при декодировании объекта вы должны иметь возможность ссылаться на идентификатор по мере необходимости из documentID свойства, а не из .data() метода

Источник: Идентификатор моментального снимка документа iOS

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

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

2. как это может работать, если у вас нет доступа к исходному документу? Все, что вам нужно, — это путь к рассматриваемому документу, и вы говорите, что он отлично работает. вы должны быть в состоянии построить свой декодер на основе имеющейся информации. docID-это просто значение, которое находится рядом с методом data (), что означает, что оно недоступно из метода data (), но является его родительским свойством.

3. Он отлично работает со стандартным декодером, но не с пользовательским декодером (или, по крайней мере, я не знаю как). Я не понимаю, о чем ты. В этом случае это также должно быть выполнимо с помощью пользовательского декодера.

Ответ №2:

Расшифруйте идентификатор документа с помощью:

 _id = try container.decode(DocumentID<String>.self, forKey: .id)
 

для соответствующей переменной:

 @DocumentID var id: String?
 

Это поместит идентификатор документа в переменную ID (обратите внимание на обязательное «_» перед идентификатором).