Я не могу передавать (читать) документы, которые содержат свойства массива, такие как Карты в Firestore.
Использование Firestore с документом, содержащим массив с простым типом String, работает как положено. Легко написать (добавить с FieldValue.arrayUnion (['data1', 'data2', 'data3']) и отправить обратно с кодом вроде:
var test2 = List<String>();
for (var item in data['items']) {
print('The item $item');
test2.add(item);
}
test2 теперь можно использовать в качестве свойства моих элементов Когда я пытаюсь использовать Список, где тип элемента становится Картой в Firestore и представляет собой простой Класс, содержащий несколько Строк и свойство даты. Я могу записать их в FireStore, но не могу прочитать их обратно.
Сбой следующего кода: (нет ошибок в консоли отладки, но он не запускается)
var test2 = List<Item>();
data['items'].forEach((item) {
var description = item['description'];
print('The description $description'); // <-- I don't get past this
final x = Item.fromMap(item); // <-- so I can't even attempt this
return test2.add(x);
});
Мне никогда не удается вызвать мой конструктор Item.fromMap: вот еще одна попытка:
// fails
final theItems = data['items'].map((x) {
return Item.fromMap(x); // <-- never get here
});
Хотя консоль отладки не говорит о наличии каких-либо проблем. Если я проверяю переменную theItems (отладчик «перебрасывает» пару строк до моего возврата) после неудачной итерации, это выглядит так:
MappedListIterable
_f:Closure
_source:List (1 item)
first:Unhandled exception:\ntype '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<String, dynamic>'\n#0 new Listing.fromMap.<anonymous closure> isEmpty:false
isNotEmpty:true
iterator:ListIterator
last:Unhandled exception:\ntype '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of
Так случилось что-то плохое, но я понятия не имею, почему!
Кто-нибудь написал и получил свойства массива Firestore, содержащие Карты? оценили!
Подробнее: снимок экрана документа
Вот код, который читает (передает) коллекцию
Stream<List<T>> collectionStream<T>({
@required String path,
@required T builder(Map<String, dynamic> data, String documentID),
@required String userId,
Query queryBuilder(Query query),
int sort(T lhs, T rhs),
}) {
Query query = Firestore.instance.collection(path);
if (queryBuilder != null) {
query = queryBuilder(query);
}
final Stream<QuerySnapshot> snapshots = query.snapshots();
return snapshots.map((snapshot) {
//print('document: path $path ${snapshot.documents[0]?.documentID}');
final result = snapshot.documents
.map((snapshot) => builder(snapshot.data, snapshot.documentID))
.where((value) => value != null)
.toList();
if (sort != null) {
result.sort(sort);
}
print('returning from CollectionStream');
return result;
});
}
. На карте возникает проблема. Функция компоновщика разрешается следующим образом:
builder: (data, documentId) {
return Listing.fromMap(data, documentId);
},
Что заканчивается здесь
factory Listing.fromMap(
Map<String, dynamic> data,
String documentId,
) {
if (data == null) {
return null;
}
final theTime = (data['createdAt'] as Timestamp).toDate();
// see above code where I fail at getting at the items property/field
Вот класс элементов:
class Item {
Item(this.description, this.imageURL, this.thumbnailURL,
{this.status = ItemStatus.active,
this.type = ListingType.free,
this.price = 0,
this.isUpdate = false,
this.createdAt});
final String description;
final String imageURL;
final String thumbnailURL;
final ItemStatus status;
final ListingType type;
final int price;
final bool isUpdate;
DateTime createdAt;
factory Item.fromMap(
Map<String, dynamic> data,
) {
if (data == null) {
return null;
}
final theTime = (data['createdAt'] as Timestamp).toDate();
return Item(
data['description'],
data['imageURL'],
data['thumbnailURL'],
status: _itemStatusFromString(data['status']),
type: data['type'] == 'free' ? ListingType.free : ListingType.flatRate,
createdAt: theTime,
);
}
Map<String, dynamic> toMap() {
// enums are for shit in Dart
final statusString = status.toString().split('.')[1];
final typeString = type.toString().split('.')[1];
return {
'description': description,
'imageURL': imageURL,
'thumbnailURL': thumbnailURL,
'itemStatus': statusString,
'price': price,
'listingType': typeString,
if (!isUpdate) 'createdAt': DateTime.now(),
if (isUpdate) 'updatedAt': DateTime.now(),
};
}
}
Вышеуказанное никогда не вызывается для чтения (у нас sh) ... оно вызывается для записи данных.