Flutter: создать список виджетов с данными из Firestore

Я хочу, чтобы на моем экране отображалось ограниченное количество товаров в GridView. Все продукты хранятся в Firebase Firestore, а их изображения — в хранилище Firebase. Для этого я использую GridView.count, одним из его параметров является List<Widget> children. Я хотел сгенерировать список с помощью List.generate и каждый раз получать продукт из Firestore и его изображение из хранилища, чтобы создать виджет, представляющий продукт. Проблема в том, что получение продуктов из Firebase является асинхронным, и функция generatorList.generate не может быть async. Более того, я возвращаю Future<List<Widget>> вместо List<Widget> в параметр childrenGridView.count Любые идеи о том, как это преодолеть?

вот мой код:


GridView.count(
  primary: false,
  crossAxisCount: 2,
  padding: const EdgeInsets.all(20),
  crossAxisSpacing: 10,
  mainAxisSpacing: 10,
  //FIXME: The argument type 'Future<List<Widget>>' can't be assigned to the parameter type 'List<Widget>':
  children: _buildGridTileList(15),
)

Future<List<Widget>> _buildGridTileList(int count) async {
    var counterCollection = await FirebaseFirestore.instance.collection("Products").doc("Counter").get();
    var counterData = counterCollection.data();
    return List.generate(
      count,
      (index) async {
        //FIXME: Doesn't work beacuse generator cannot be async!!
        var avatarUrl = await FirebaseStorage.instance.ref('${counterData[index]}').child('${counterData[index]}').getDownloadURL();
        return Container(
          child: Center(
            child: NetworkImage(avatarUrl),
          ),
        );
      }
    );
  }
Интеграция Angular - Firebase Analytics
Интеграция Angular - Firebase Analytics
Узнайте, как настроить Firebase Analytics и отслеживать поведение пользователей в вашем приложении Angular.
1
0
1 620
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы не можете иметь асинхронный код в своей функции сборки, потому что это функция, собирающая дерево виджетов для немедленного рендеринга на экран, вместо этого вы используете виджет StreamBuilder, который дает вам доступ к асинхронным событиям, поток прослушивает будущие данные поступающий из Firebase, и перестраивает этот раздел дерева виджетов при поступлении асинхронного события. вот как это делается, этот код должен быть близок к тому, что вам нужно:

return StreamBuilder(
  stream: FirebaseFirestore.instance.collection("Products").snapshots(),
  builder:
  (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
  if (!snapshot.hasData) {
    return Container();
  } else {
    return GridView.count(
      primary: false,
      crossAxisCount: 2,
      padding: const EdgeInsets.all(20),
      crossAxisSpacing: 10,
      mainAxisSpacing: 10,
      children: List.generate(snapshot.data.docs.length, (index) {
        return Image.network(snapshot.data.docs[index].imageUrl);
        }),
      );
    }
  });
}

Другие вопросы по теме