Получение данных о каждом продукте из облачного хранилища firebase

Я загрузил две информации о продукте в облачный хранилище, как указано ниже.

введите описание изображения здесь

Я использовал способ загрузить каждый продукт и показать его в виде плитки ..

Это метод, который я использовал для получения данных из облачного хранилища, и когда я печатаю, длина документа успешно показывает «2». ????

void getData() async {
    QuerySnapshot snapshot =
        await FirebaseFirestore.instance.collection('kollamProducts').get();
    snapshot.docs.forEach((document) {
      category = document['category'];
      id = document['id'];
      name = document['name'];
      shop = document['shop'];
      quantity = document['quantity'];
      images = List.from(document['images']);
      sizes = List.from(document['sizes']);
    });

    if (snapshot.docs.length != 0) {
      setState(() {
        prodL = snapshot.docs.length;
      });
    }
  }

Это виджет плитки сетки, который я создал. В этом случае он использует другой виджет под названием Single Product в качестве itemBuilder.

  Widget build(BuildContext context) {
    return GridView.builder(
      physics: NeverScrollableScrollPhysics(),
      shrinkWrap: false,
      primary: false,
      itemCount: prodL,
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
      ),
      itemBuilder: (BuildContext context, int index) {
        return SingleProdc(
          product_name: name,
          product_picture: images[0],
          product_image1: images[1],
          product_image2: images[2],
          product_shop: shop,
        );
      },
    );
  }

А единственный виджет rpoduct упорядочивает все на карточке и показывает продукт в плитке сетки.

class SingleProdc extends StatelessWidget {
  final product_name;
  final product_picture;
  final product_image1;
  final product_image2;
  final product_shop;

  SingleProdc(
      {this.product_name,
      this.product_picture,
      this.product_image1,
      this.product_image2,
      this.product_shop});
  @override
  Widget build(BuildContext context) {
    return Card(
      child: Hero(
        tag: product_name,
        child: Material(
          borderRadius: BorderRadius.circular(50),
          child: InkWell(
            borderRadius: BorderRadius.circular(50),
            onTap: () => Navigator.of(context).push(MaterialPageRoute(
                builder: (context) => ProductDetails(
                      product_detail_name: product_name,
                      product_detail_picture: product_picture,
                      product_detail_image1: product_image1,
                      product_detail_image2: product_image2,
                      product_detail_shop: product_shop,
                    ))),
            child: GridTile(
              header: Container(
                height: 30,
                color: Colors.black38,
                child: Center(
                    child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Icon(
                      Icons.home,
                      color: Colors.white,
                    ),
                    Text(
                      product_shop,
                      style: GoogleFonts.poppins(color: Colors.white),
                    ),
                  ],
                )),
              ),
              footer: Container(
                  height: 50,
                  color: Colors.black38,
                  child: Column(
                    children: [
                      Text(
                        product_name,
                        style: GoogleFonts.poppins(
                          color: Colors.white,
                          fontSize:
                              product_name.toString().length > 9 ? 10 : 15,
                        ),
                      ),
                      Text(
                        "\u{20B9} 500",
                        style: GoogleFonts.poppins(
                            color: Colors.white, fontSize: 15),
                      ),
                    ],
                  )),
              child: Image.network(
                product_picture,
                fit: BoxFit.cover,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

Проблема в том, что когда продукт отображается вместо двух разных продуктов, первый дублируется .. Это не то, что я хочу .. Снимок.docs.length говорит, что есть 2 продукта .. Тогда почему первый является тиражируется .. Пожалуйста, помогите мне.


person AliMohammed Manzoor    schedule 25.02.2021    source источник
comment
Я новичок в этом, но я не вижу, где хранятся значения категории, идентификатора, магазина, количества. Не будут ли доступны только последние значения? Они перезаписываются при каждом прочтении документа. Вы хотите вернуть List ‹Product› из getData и использовать этот список для конструктора.   -  person user14624595    schedule 25.02.2021


Ответы (2)


Собственно ошибка здесь:

void getData() async {
    QuerySnapshot snapshot =
        await FirebaseFirestore.instance.collection('kollamProducts').get();
    snapshot.docs.forEach((document) {
      category = document['category'];
      id = document['id'];
      name = document['name'];
      shop = document['shop'];
      quantity = document['quantity'];
      images = List.from(document['images']);
      sizes = List.from(document['sizes']);
    });

    if (snapshot.docs.length != 0) {
      setState(() {
        prodL = snapshot.docs.length;
      });
    }
  }

Вы присваиваете значения некоторой фиксированной переменной. Что вам нужно сделать, так это вернуть список:

Future<List<dynamic>> getData() async {
  List<dynamic> temp = List();
    QuerySnapshot snapshot =
        await FirebaseFirestore.instance.collection('kollamProducts').get();
    snapshot.docs.forEach((document) {
    temp.add(
    {
      category = document['category'];
      id = document['id'];
      name = document['name'];
      shop = document['shop'];
      quantity = document['quantity'];
      images = List.from(document['images']);
      sizes = List.from(document['sizes']);
    }
  );
});

    if (snapshot.docs.length != 0) {
      setState(() {
        prodL = snapshot.docs.length;
      });
    }
    return temp;
  }

Теперь вы можете использовать элементы в списке для доступа к данным и отображения виджетов.

person Preet Shah    schedule 25.02.2021
comment
Спасибо, брат ... Это сработало ... Теперь я понял концепцию ... Большое спасибо, брат ... - person AliMohammed Manzoor; 25.02.2021
comment
Пожалуйста. Рад помочь. - person Preet Shah; 25.02.2021

Я думаю, это потому, что getData возвращает void вместо Future<void>. Попробуйте изменить это, а также, куда бы вы ни звонили getData(), используйте await getData().

Изменить: я пытаюсь сказать следующее. Удалите await getData() из initState и сделайте это.

Widget build(BuildContext context) {
  return FutureBuilder(
    future: getData(),
    builder:(context, snapshot) {
      if(snapshot.connectionState == ConnectionState.done){
        return GridView.builder(
        physics: NeverScrollableScrollPhysics(),
        shrinkWrap: false,
        primary: false,
        itemCount: prodL,
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2,
        ),
        itemBuilder: (BuildContext context, int index) {
          return SingleProdc(
            product_name: name,
            product_picture: images[0],
            product_image1: images[1],
            product_image2: images[2],
            product_shop: shop,
          );
        },
        );
      }
    },
  );
}
person rkdupr0n    schedule 25.02.2021
comment
Я переключился на Future ‹void›, и функция была вызвана в initState. когда я добавляю ожидание, он показывает ошибку, подобную этой _ProductKollamListState.initState () вернул Future. State.initState () должен быть недействительным методом без ключевого слова async. - person AliMohammed Manzoor; 25.02.2021
comment
Подождите, почему вы вызываете это в initState? Nvm, может попробовать использовать FutureBuilder поверх GirdView? - person rkdupr0n; 25.02.2021
comment
И удалите getData() из initState и вставьте future для FutureBuilder - person rkdupr0n; 25.02.2021
comment
ты можешь изменить мой код .. я не понял - person AliMohammed Manzoor; 25.02.2021