# #google-cloud-firestore #flutter-web
Вопрос:
У меня в коллекции пользователей есть несколько документов, в которых еще нет всех возможных полей.
Получение моих пользователей из Firestore (с помощью cloud_firestore: ^2.2.1) выдает ошибку.
Bad state: field does not exist within the DocumentSnapshotPlatform
Я спровоцировал эту ошибку внутри блока try-catch.
...
factory User.fromFirestore(DocumentSnapshot doc) {
try {
print(doc.get('some-missing-field'));
} catch (e) {
print(e);
}
return User(
id: doc.id,
email: doc.get('email') ?? '',
displayName: doc.get('displayName') ?? '',
fieldfoo: doc.get('fieldfoo') ?? '',
fieldbar: doc.get('fieldbar') ?? [],
);
}
}
...
В какой момент я пропустил, чтобы сказать flutter, что он должен заполнить недостающие поля фиктивными значениями?
Существуют ли какие-либо лучшие практики? Сталкивался ли кто-нибудь с подобной проблемой?
Ответ №1:
Если вы используете нулевую безопасность, вы можете получить ее следующим образом:
Map<String, dynamic>? data = docSnapshot.data();
var value = data?['field_name'] ?? '';
Комментарии:
1. Возражать? пакет данных (): cloud_firestore/cloud_firestore. dart Содержит все данные этого снимка документа. Значение типа «Объект?» не может быть присвоено переменной типа » Карта<Строка, динамическая>?». Попробуйте изменить тип переменной или присвоить правому типу значение » Сопоставить<Строка, динамическая>?». Похоже, что мой снимок имеет тип <Объект?>, но почему?
2. Можете ли вы показать нам скриншот вашей базы данных в том месте, где вы получаете данные.
Ответ №2:
Решение состояло в том, чтобы сопоставлять DocumentSnapshot с <строкой, динамической> при каждом появлении.
Полученная функция выглядит следующим образом
...
factory User.fromFirestore(DocumentSnapshot<Map<String, dynamic>> doc) {
Map data = doc.data()!;
return User(
id: doc.id,
email: data['email'] ?? '',
displayName: data['displayName'] ?? '',
language: data['language'] ?? '',
affiliatedOrganizations: data['affiliatedOrganizations'] ?? [],
isAdmin: data['isAdmin'] ?? false,
isEditor: data['isEditor'] ?? false,
);
}
...
Этот «запрос» приводит ко всем пользователям.
final Stream<QuerySnapshot<Map<String, dynamic>>> _usersStream =
DatabaseService().usersCollection.snapshots();
Когда я сортирую по полю, которого нет в некоторых пользовательских документах, эти пользовательские документы не будут отображаться
final Stream<QuerySnapshot<Map<String, dynamic>>> _usersStream =
DatabaseService().usersCollection.orderBy('displayName').snapshots();
Не у всех пользователей есть «Имя дисплея», поэтому они не указаны в моем результате.
Кто-нибудь знает, как это обойти?