将新项目写入 Firebase 时出现错误状态错误

时间:2021-03-27 10:08:59

标签: firebase flutter google-cloud-firestore

每当我尝试编写新项目时,都会收到以下错误。

<块引用>

错误状态:无法获取 DocumentSnapshotPlatform 上的字段 不存在

该功能仅在添加第一个项目时有效,当我尝试添加具有相同“restaurantId”的新项目时,出现错误。我不明白为什么它只是第一次添加。 另外,如果可能,请帮我优化代码。

void addItemCart(String restaurantId, String restItemId, double price,
      int quantity) async {
    List<CartItem> cartItems = [];
    final String authId = FirebaseAuth.instance.currentUser.uid;
    Map<String, dynamic> restData;
    final newRest = await FirebaseFirestore.instance
        .collection('restaurants')
        .doc(restaurantId)
        .collection('restaurantItems')
        .doc(restItemId)
        .get()
        .then((value) => restData = value.data());

    int restQuantity = restData['quantity'];
    String restIdName = restData['name'];

    try {
      if (authId != null) {
        final cart = await FirebaseFirestore.instance
            .collection('users')
            .doc(authId)
            .collection('cart')
            .doc(authId)
            .get();

        if (!cart.exists) {
          await FirebaseFirestore.instance
              .collection('users')
              .doc(authId)
              .collection('cart')
              .doc(authId)
              .set({'restaurantId': restaurantId});

          await FirebaseFirestore.instance
              .collection('users')
              .doc(authId)
              .collection('cart')
              .doc(authId)
              .collection('restItemId')
              .doc(restItemId)
              .set(
            {'price': price * quantity, 'quantity': 1, 'name': restIdName},
          );
          _items.add(
            CartItem(
                id: restItemId,
                title: restIdName,
                price: price,
                quantity: quantity,
                restaurantId: restaurantId),
          );
        } else if (cart.data()['restaurantId'] == restaurantId) {
          print('$restIdName in If loop');
          print('$quantity in If loop');
          // print('$quantity in If loop');
          try {
            await FirebaseFirestore.instance
                .collection('users')
                .doc(authId)
                .collection('cart')
                .doc(authId)
                .collection('restItemId')
                .doc(restItemId)
                .get()
                .then(
              (value) async {
                print('${value['quantity']} value');
                if (value['quantity'] <= restQuantity) {
                  await FirebaseFirestore.instance
                      .collection('users')
                      .doc(authId)
                      .collection('cart')
                      .doc(authId)
                      .collection('restItemId')
                      .doc(restItemId)
                      .set({
                    'name': value.data()['name'],
                    'quantity': value.data()['quantity'] == null
                        ? 0
                        : value.data()['quantity'] + 1,
                    'price': price * (value.data()['quantity'] + 1)
                  });
                  _items.add(
                    CartItem(
                        id: restItemId,
                        title: restIdName,
                        price: price,
                        quantity: quantity,
                        restaurantId: restaurantId),
                  );
                }
              },
            );
          } catch (error) {
            print(error);
          }
        } else {
          print('alert! new rest');
          // Return an alert to change the restauran name to the user
        }
      }
    } catch (error) {
      print(error);
    }
  }

感谢您的时间和支持。

2 个答案:

答案 0 :(得分:1)

错误告诉我们两件事:

1- 它位于 get() 查询之一中。而且您只有其中三个,因此我们可以消除您的其他 firestore 功能。

2- 表示您正在尝试从不存在的文档中检索数据。

如果你的第二部分代码:

await FirebaseFirestore.instance
.collection('users')
.doc(authId)
.collection('cart')
.doc(authId)
.collection('restItemId')
.doc(restItemId)
.get()
  • 确保存在 .doc(restItemId)。 仔细检查您是否传递了存在的 .doc() ID。您在创建\设置文档时不会遇到任何问题,因为 Firebase 会以您指定的结构为您创建它们,即使它们不存在。但是它不会得到任何不存在的东西,并且会抛出你看到的错误。您的代码的第一部分有效,因为文档尚不存在而您创建了它们,第二部分您要求 firebase 提供您认为已创建但实际上并未创建的文档,或者可能是使用您认为的 ID 创建的指定,但没有。

  • 在监控 Firebase 控制台的同时运行您的函数,查看文档和子集合是如何创建的,记下 ID,并对其进行跟踪。我建议打破用于创建条目的逻辑,因为正如您可能已经看到的那样,即使格式很好,它也会变得非常混乱。

  • 创建新条目的逻辑总是相同的,因此将您的功能分散到各个部分中,检查某些内容是否存在,一个简单的 if 语句,就像您使用的那样,并根据条件将它们发送到两个函数,即 void addNewRestaurant()void existingRestaurant()

答案 1 :(得分:0)

void addItemCart(String restaurantId, String restItemId, double price,
      int quantity) async {
    List<CartItem> cartItems = [];
    final String authId = FirebaseAuth.instance.currentUser.uid;
    Map<String, dynamic> restData;
    final newRest = await FirebaseFirestore.instance
        .collection('restaurants')
        .doc(restaurantId)
        .collection('restaurantItems')
        .doc(restItemId)
        .get()
        .then((value) => restData = value.data());

    int restQuantity = restData['quantity'];
    String restIdName = restData['name'];

    try {
      if (authId != null) {
        final cart = await FirebaseFirestore.instance
            .collection('users')
            .doc(authId)
            .collection('cart')
            .doc(authId)
            .get();

        final value = await FirebaseFirestore.instance
            .collection('users')
            .doc(authId)
            .collection('cart')
            .doc(authId)
            .collection('restItemId')
            .doc(restItemId)
            .get();

        // if(restItem.exists)
        print('${value.data()}: restaurant item data');

        if (!cart.exists) {
          await FirebaseFirestore.instance
              .collection('users')
              .doc(authId)
              .collection('cart')
              .doc(authId)
              .set({'restaurantId': restaurantId});

          await FirebaseFirestore.instance
              .collection('users')
              .doc(authId)
              .collection('cart')
              .doc(authId)
              .collection('restItemId')
              .doc(restItemId)
              .set(
            {'price': price * quantity, 'quantity': 1, 'name': restIdName},
          );
          _items.add(
            CartItem(
                id: restItemId,
                title: restIdName,
                price: price,
                quantity: quantity,
                restaurantId: restaurantId),
          );
        } else if (cart.data()['restaurantId'] == restaurantId) {
          print('$restIdName in If loop');
          print('$quantity in If loop');
          // print('$quantity in If loop');
          try {
        
            if (!value.exists) {
              print('$restIdName does not exist');
              await FirebaseFirestore.instance
                  .collection('users')
                  .doc(authId)
                  .collection('cart')
                  .doc(authId)
                  .collection('restItemId')
                  .doc(restItemId)
                  .set(
                {'name': restIdName, 'quantity': 1, 'price': price},
              );
            } else if (value['quantity'] < restQuantity) {
              await FirebaseFirestore.instance
                  .collection('users')
                  .doc(authId)
                  .collection('cart')
                  .doc(authId)
                  .collection('restItemId')
                  .doc(restItemId)
                  .set(
                {
                  'name': value.data()['name'],
                  'quantity': value.data()['quantity'] == null
                      ? 0
                      : value.data()['quantity'] + 1,
                  'price': price * (value.data()['quantity'] + 1)
                },
              );
              _items.add(
                CartItem(
                    id: restItemId,
                    title: restIdName,
                    price: price,
                    quantity: quantity,
                    restaurantId: restaurantId),
              );
            }
          } catch (error) {
            print(error);
          }
        } else {
          print('alert! new rest');
          // Return an alert to change the restauran name to the user
        }
      }
    } catch (error) {
      print(error);
    }
  }