Я ужасно запутался здесь ... каков правильный синтаксис для перечисления массива из Firestore с помощью FutureBuilder, если мне нужно выполнить запрос документа (где)?
Структура базы данных Firestore:
- [companies]
- [doc]
- [gallery]
- [doc]
- [reference] <- (ie, companies/doc)
- [gallery_images] // List these, but show only images that match where() query
Вот мой текущий код:
Future<List<dynamic>> getGallery() async {
var firestore = Firestore.instance;
DocumentReference docRef = firestore.collection('companies').document(widget.docID);
var ref = firestore.collection('galleries').where('companyRef', isEqualTo: docRef).getDocuments();
return ref.get().then((datasnapshot) {
if (datasnapshot.exists) {
List<dynamic> imageArray = datasnapshot.data['gallery_images'].toList();
return imageArray;
} else {
print("Please just work...");
}
},
);
}
FutureBuilder(
future: getGallery(),
builder: (context, AsyncSnapshot<List<dynamic>> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: Text("Loading..."),
);
} else {
return GridView.builder(
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemCount: *length*,
itemBuilder: (BuildContext context, int index) {
return ViewGalleryItemThumbnail(
viewGalleryItem: snapshot.data[index],
....
Был бы очень признателен, если бы кто-нибудь показал мне, где я ошибаюсь!
Не совсем понятно, как выглядит ваша схема Cloud Firestore, но это, скорее всего, вернет вам правильный список динамики. (Обратите внимание, что, добавив универсальную карту на карту, вы можете вернуть список того, что вам нужно, например .map<SomeRealType>((snap) => snap.data['gallery_images'])
.)
Когда вы застряли с FutureBuilder
, иногда полезно временно вернуться к виджету с отслеживанием состояния. Переопределите initState
и вызовите слегка измененный getGallery
, который не возвращает значение в конце, а присваивает его переменной-члену внутри setState
. Таким образом, есть много возможностей для печати заявлений. Кроме того, попробуйте преобразовать любые .then
s в асинхронной функции в линейный ряд await
s. Это облегчает чтение (и ваши отладочные отпечатки выводятся в линейном разумном порядке).
Future<List<dynamic>> getGallery() async {
var firestore = Firestore.instance;
var docRef = firestore.collection('companies').document(widget.docID);
var querySnap = await firestore
.collection('galleries')
.where('companyRef', isEqualTo: docRef)
.getDocuments();
return querySnap.documents
.map((snap) => snap.data['gallery_images'])
.toList();
}
Вы уверены, что на самом деле запрос возвращает 8 изображений? Что производят print(snapshot.data.runtimeType);
и/или print(snapshot.data);
?
Хорошо, это странно - print(snapshot.data) возвращает 4 полных URL-адреса и 1 частичный URL-адрес (pastebin.com/HNbLhy9g) ?? RuntimeType возвращает список<dynamc>
Сокращены URL-адреса звездочками. Последний URL-адрес является полным, как он появляется. Также заметил две открывающиеся квадратные скобки и отсутствие закрывающих скобок. Очень странно?
Усечение - это просто консоль, у которой не хватает места. Итак, у нас есть массив, который содержит другой массив (строк). Итак, в firestore, держу пари, gallery_images
определяется как массив. Да, в этом есть смысл: ваш запрос возвращает список документов (может быть, только один — да, именно поэтому вы видите длину 1), содержащий массив изображений. Итак, в вашем конструкторе используйте snapshot.data[0][index]
— берёте нулевой документ и индексируете его изображения.
Вы абсолютный лучший! Теперь все работает отлично :D Большое спасибо за вашу помощь и объяснения - теперь все намного яснее. Очень ценю это!
Большое спасибо за ваше объяснение и пример, очень признателен! Я почти закончил — похоже, он возвращает массив изображений, но как мне вставить его в FutureBuilder? Если у меня есть восемь изображений в галерее_изображений, то используйте getGallery() в FutureBuilder, print(snapshot.data.length) возвращает только 1 (я предполагаю, что он считает массив целиком, а не отдельные изображения). Если я вручную укажу 1 в качестве количества элементов в GridView.builder, я могу вернуть первое изображение в массиве с помощью «snapshot.data[index][0]». Вы видите, где я ошибаюсь?