# #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()
метода
Комментарии:
1. Но в моем методе инициализации у меня нет доступа к исходному документу. Для этого потребуется довольно много рефакторинга. Дело в том, что он отлично работает без специального декодера.
2. как это может работать, если у вас нет доступа к исходному документу? Все, что вам нужно, — это путь к рассматриваемому документу, и вы говорите, что он отлично работает. вы должны быть в состоянии построить свой декодер на основе имеющейся информации. docID-это просто значение, которое находится рядом с методом data (), что означает, что оно недоступно из метода data (), но является его родительским свойством.
3. Он отлично работает со стандартным декодером, но не с пользовательским декодером (или, по крайней мере, я не знаю как). Я не понимаю, о чем ты. В этом случае это также должно быть выполнимо с помощью пользовательского декодера.
Ответ №2:
Расшифруйте идентификатор документа с помощью:
_id = try container.decode(DocumentID<String>.self, forKey: .id)
для соответствующей переменной:
@DocumentID var id: String?
Это поместит идентификатор документа в переменную ID (обратите внимание на обязательное «_» перед идентификатором).