简体   繁体   English

使用 Stream 检索数据<querysnapshot>在 Firebase 和 Flutter</querysnapshot>

[英]Retrieving Data with Stream<QuerySnapshot> in Firebase with Flutter

Maybe it's a newbie question, but I'm learning flutter and some stuffs like async, await, Future, doesn't fit in my mind yet.也许这是一个新手问题,但我正在学习 flutter 和一些东西,如异步、等待、未来,还不适合我的想法。 Anyway, what I want to do is get the value from "field.documents[index]["name"]" and built a List.无论如何,我想做的是从“field.documents[index][”name“]”中获取值并构建一个列表。 Here is my code:这是我的代码:

String productName;

Stream<QuerySnapshot> productRef = Firestore.instance
    .collection("stores")
    .document(name)
    .collection("products")
    .snapshots();
productRef.forEach((field) {
  field.documents.asMap().forEach((index, data) {
    productName = field.documents[index]["name"];
    //IF I PRINT HERE, IT SHOWS THE PRODUCTS. 
  });
});
BUT IF I PRINT HERE, I GOT A NULL VALUE

I want to get productName outside the forEach.我想在 forEach 之外获取 productName。 When I print, it first prints null. I´ll post my entire function too:当我打印时,它首先打印 null。我也会发布我的整个 function:

List mapToList({DocumentSnapshot doc, List<DocumentSnapshot> docList}) {
    if (docList != null) {
      List<Store> storeList = [];
      docList.forEach((document) {
        String name = document.data[StringConstant.nameField];
        num score = document.data[StringConstant.scoreField];
        String delivery = document.data[StringConstant.deliveryField];
        String photo = document.data[StringConstant.photoField];
        String description = document.data[StringConstant.descriptionField];
        String open = document.data[StringConstant.openField];
        String close = document.data[StringConstant.closeField];
        GeoPoint geoPoint = document.data[StringConstant.positionField]
            [StringConstant.geopointField];

        bool isOpen = document.data[StringConstant.isOpenField];
        final currentHour = DateTime.now();
        final openHour = DateTime.parse(open).hour;
        final closeHour = DateTime.parse(close).hour;
        int openMin = DateTime.parse(open).minute;
        int closeMin = DateTime.parse(close).minute;
        if (openHour <= currentHour.hour && currentHour.hour <= closeHour) {
          isOpen = true;
          if ((currentHour.hour == openHour && currentHour.minute < openMin) ||
              (currentHour.hour == closeHour &&
                  currentHour.minute > closeMin)) {
            isOpen = false;
          }
        } else {
          isOpen = false;
        }
        final double meter = distance(
          LatLng(latitude, longitude),
          LatLng(geoPoint.latitude, geoPoint.longitude),
        );

        String productName;

        Stream<QuerySnapshot> productRef = Firestore.instance
            .collection("stores")
            .document(name)
            .collection("products")
            .snapshots();
        productRef.forEach((field) {
          field.documents.asMap().forEach((index, data) {
            productName = field.documents[index]["name"];
          });
        });

        if (meter <= range && isOpen == true) {
          Store otherStore = Store(name, photo, score.toDouble(), delivery,
              meter, description, productName, 10.0, "");
          storeList.add(otherStore);
        }
      });
      return storeList;
    } else {
      return null;
    }
  }

Can somebody help me?有人可以帮我吗? I know its something with asynchronous programming, but I'm learning.我知道它与异步编程有关,但我正在学习。 Thanks!!!谢谢!!!

What I would do is in here:我要做的是在这里:

List<String> productName= [];

Stream<QuerySnapshot> productRef = Firestore.instance
    .collection("stores")
    .document(name)
    .collection("products")
    .snapshots();
productRef.forEach((field) {
  field.documents.asMap().forEach((index, data) {
    productName.add(field.documents[index]["name"]);
  });
});

You initialize an array outside of the query so you can add a String to it each time the '.forEach' iterates.您在查询之外初始化一个数组,以便每次“.forEach”迭代时都可以向其中添加一个字符串。 What you can do instead of manually inputting each data in your function, you can create a Data Model to store the data that is in your database into a local variable which is more flexible than manually doing field.documents['dataField'].您可以做什么而不是手动输入 function 中的每个数据,您可以创建一个数据 Model 将数据库中的数据存储到一个局部变量中,这比手动执行 field.documents ['dataField'] 更灵活。 Here is some useful link: https://medium.com/flutter-community/parsing-complex-json-in-flutter-747c46655f51这是一些有用的链接: https://medium.com/flutter-community/parsing-complex-json-in-flutter-747c46655f51

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: StreamBuilder<QuerySnapshot>(
          stream: FirebaseFirestore
                  .instance.
                  .collection('users') // 👈 Your desired collection name here
                  .snapshots(), 
          builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
            if (snapshot.hasError) {
              return const Text('Something went wrong');
            }
            if (snapshot.connectionState == ConnectionState.waiting) {
              return const Text("Loading");
            }
            return ListView(
                children: snapshot.data!.docs.map((DocumentSnapshot document) {
              Map<String, dynamic> data =
                  document.data()! as Map<String, dynamic>;
              return ListTile(
                title: Text(data['fullName']), // 👈 Your valid data here
              );
            }).toList());
          },
        ),
      ),
    );
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM