Как загрузить список объектов в Firestore - PullRequest
0 голосов
/ 17 апреля 2020

Я занимаюсь разработкой приложения для флаттера с помощью FireStore.

Я объявил переменную total и список объектов, которые должны быть заполнены некоторыми данными из коллекции, называемой «корзиной», а затем загрузил эти данные в коллекцию, которая называется 'orders'

Этот код извлекает данные из коллекции 'cart':


void submitOrder() async {

    List<CartItem> products =[];
    double total =0;
    CartItem temp= CartItem(customerId:'' ,itemId:'' ,id: '', title: '', quantity:0, price: 0);

    DatabaseService().cartCollection.getDocuments().then(

       (snapshot) => snapshot.documents.forEach((doc) {

          temp = CartItem(
            customerId: user.uid, 
            itemId: doc.data['itemId'].toString(),
            id: doc.documentID.toString(), 
            title: doc.data['itemName'].toString(),
            quantity: int.tryParse(doc.data['quantity'].toString()) , 
            price: double.tryParse( doc.data['price'].toString()));

            total += temp.quantity*temp.price;
            print(total);  /// This print shows accurate total
            products.add(temp);
            }
          ),
        );
          // Send data to setOrderData in db class to set new doc in order collection                            
          DatabaseService().setOrderData(products, total, user.uid, branchId, 'open');

}

метод setOrderData в классе БД:

  // Add Order
Future setOrderData(List<CartItem> cartProducts, double total, String customerId, String branchId, String status ) async { 
    final timestamp = DateTime.now();
    return await orderCollection.document(uid).setData(
      {
        'customerId': customerId,
        'branchId': branchId,
        'status': status ,
        'amount': total.toString(), //
        'dateTime': timestamp.toIso8601String(),
        'products': cartProducts.map((cp) => {
          'id': cp.id,
          'title': cp.title,
          'quantity': cp.quantity,
          'price': cp.price,
          }).toList(),
      });
  }

данные в FireStore показывают, что продукты и всего равно нулю?

Ссылка на изображение:

Data in Firestore

Если кто-нибудь может мне помочь, я был бы благодарен.

1 Ответ

0 голосов
/ 17 апреля 2020

Я очень рекомендую использовать средство форматирования кода в вашем коде, поскольку это значительно повышает вероятность того, что люди смогут обнаружить проблемы, подобные той, что у вас есть. Когда я переформатирую первый кодовый блок, которым вы поделились, он становится:

void submitOrder() async {
  List<CartItem> products = [];
  double total = 0;
  CartItem temp = CartItem(
      customerId: '', itemId: '', id: '', title: '', quantity: 0, price: 0);

  DatabaseService().cartCollection.getDocuments().then(
        (snapshot) => snapshot.documents.forEach((doc) {
          temp = CartItem(
              customerId: user.uid,
              itemId: doc.data['itemId'].toString(),
              id: doc.documentID.toString(),
              title: doc.data['itemName'].toString(),
              quantity: int.tryParse(doc.data['quantity'].toString()),
              price: double.tryParse(doc.data['price'].toString()));

          total += temp.quantity * temp.price;
          print(total);

          /// This print shows accurate total
          products.add(temp);
        }),
      );
  // Send data to setOrderData in db class to set new doc in order collection
  DatabaseService().setOrderData(products, total, user.uid, branchId, 'open');
}

. В этом формате мне сразу становится ясно, что вы звоните setOrderData до того, как произойдет любой из вызовов products.add(temp).

Это потому, что данные загружаются из Firestore асинхронно. Поскольку это может занять некоторое время, ваш основной код (включая return) продолжается, поэтому пользовательский интерфейс не блокируется. Затем, когда данные доступны, вызывается ваш обратный вызов then.

Это означает, что любой код, которому нужны данные из Firestore, должен находиться внутри обратного вызова then. Таким образом, в вашем случае, решение может быть таким же простым, как перемещение вызова на setOrderData внутрь then:

void submitOrder() async {
  List<CartItem> products = [];
  double total = 0;
  CartItem temp = CartItem(
      customerId: '', itemId: '', id: '', title: '', quantity: 0, price: 0);

  DatabaseService().cartCollection.getDocuments().then(
        (snapshot) => snapshot.documents.forEach((doc) {
          temp = CartItem(
              customerId: user.uid,
              itemId: doc.data['itemId'].toString(),
              id: doc.documentID.toString(),
              title: doc.data['itemName'].toString(),
              quantity: int.tryParse(doc.data['quantity'].toString()),
              price: double.tryParse(doc.data['price'].toString()));

          total += temp.quantity * temp.price;
          print(total);

          /// This print shows accurate total
          products.add(temp);
        }),
        // Send data to setOrderData in db class to set new doc in order collection
        DatabaseService().setOrderData(products, total, user.uid, branchId, 'open');
    );
}

Итак, что нужно от этого отнять:

  1. Всегда форматируйте свой код, так как вам и другим будет проще понять поток и найти проблемы.
  2. Данные загружаются из Firestore (и большинства облачных API) асинхронно, и вы можете использовать только данные внутри обратного вызова then() или с помощью await.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...