0

I am building an app where it collects all the orders and order details placed from Firebase. I have to get 2 things

  • Salon details from contactnumber which I saved using singleton method once the user logs in
  • Customer details from CustID

What happens right now is that during debugging I created this button, on pressing it fetches the salon details from database. But now, the details will only get fetched when I

  1. Click the button first
  2. Hot restart the app

Only then the streambuilder fetched the data Here are my code snippets causing the problem :

Future<void> getSalonFromContact(String saloonContact) async {
    await for (var docs in firestore.collection('Saloon').snapshots()) {
      //  final loop = snap.data!.docs;
      for (var variable in docs.docs) {
        if (variable.get(FieldPath(['Contact'])) == saloonContact) {
          aadhar = variable.get(FieldPath(['Aadhar']));

          getOrdersList(aadhar);
        }
      }
    }
  }

  Future<void> getOrdersList(String aadhar) async {
    ordersList.clear();
    await for (var docs in firestore
        .collection('orders')
        .where('SalonID', isEqualTo: aadhar)
        .snapshots()) {
      for (var variable in docs.docs) {
        if (variable.get('SalonID') == aadhar) {
          ordersList.add(variable.data());

          print('My orderlist is $ordersList');
        } else {
          continue;
        }
      }
    }
  }

  Future<void> getCustomerDetails(String custID) async {
    await for (var docs in firestore
        .collection('Customers')
        .where('Customer_Uid', isEqualTo: custID)
        .snapshots()) {
      //  final loop = snap.data!.docs;
      for (var variable in docs.docs) {
        print(variable.data());
        if (variable.get(FieldPath(['Customer_Uid'])) == custID) {
          customerDetails.add(variable.data());
          print('My customer details are ${customerDetails}');
        }
      }
    }
  }

  @override
  void didChangeDependencies() async {
    await getSalonFromContact(contactNumber);
    for (int i = 0; i < ordersList.length; i++) {
      await getCustomerDetails(ordersList[i]['CustomerID']);
    }
    // TODO: implement didChangeDependencies
    super.didChangeDependencies();
  }

These codes are for finding out the details.

And this is my StreamBuilder code :

 StreamBuilder<QuerySnapshot>(
                      stream: FirebaseFirestore.instance
                          .collection('orders')
                          .where('SalonID', isEqualTo: aadhar)
                          .snapshots(),
                      builder: (context, snapshot) {
                        didChangeDependencies();
                        if (snapshot.connectionState ==
                            ConnectionState.waiting) {
                          return Text('Loading...');
                        } else {
                          List<AppointmentCard> listitems = [];

                          return ListView(
                            physics: NeverScrollableScrollPhysics(),
                            shrinkWrap: true,
                            children: snapshot.data!.docs
                                .asMap()
                                .map((index, DocumentSnapshot document) {
                                  getCustomerDetails(document['CustomerID']);
                                  return MapEntry(
                                    index,
                                    AppointmentCard(
                                      isCompleted: document['Status'],
                                      name: customerDetails[index]['Name'],
                                      contact: customerDetails[index]
                                          ['Contact'],
                                      services: Flexible(
                                        child: ListView.builder(
                                            shrinkWrap: true,
                                            padding: const EdgeInsets.all(8),
                                            itemCount:
                                                document['Requested_Service']
                                                    .length,
                                            itemBuilder: (BuildContext context,
                                                int index) {
                                              return Text(
                                                  document['Requested_Service']
                                                      [index]['name']);
                                            }),
//                                child: Text(
//                                  //    "Text",
//                                  " ${ordersList[i]['Requested_Service']} ",
////                                      .join(' '),
//
//                                  softWrap: true,
//                                ),
                                      ),
                                    ),
                                  );
                                })
                                .values
                                .toList(),
                          );
                        }
                      }),

Any idea what is going wrong and how I can fetch the data without the button and hot restart?

wamika
  • 21
  • 1
  • 8

1 Answers1

0

You use getCustomerDetails(document['CustomerID']); in before MapEntry and it is an asynchronous function. It will return probably after the MapEntry is built. You have to await getCustomerDetails function before put your variables which is updating in getCustomerDetails function.

Hazar Belge
  • 1,009
  • 4
  • 20