mustafa zaki
mustafa zaki

Reputation: 407

Bad State Error while writing a new item to firebase

I am getting the following error whenever I try to write a new item.

Bad state: cannot get a field on a DocumentSnapshotPlatform which does not exist

The function works only while adding the first item, when I try to add a new item with the same 'restaurantId' I get the error. I don't understand why it's adding for the first time only. Also, please help me optimise the code if possible.

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);
    }
  }

Thanks for your time and support.

Upvotes: 0

Views: 72

Answers (2)

mustafa zaki
mustafa zaki

Reputation: 407

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);
    }
  }

Upvotes: 0

Huthaifa Muayyad
Huthaifa Muayyad

Reputation: 12353

The error tell us two things:

1- That it's in one of the get() queries. And you only have three of them, so we can eliminate your other firestore functions.

2- It says that you are trying to retrieve data, from inside a document that does not exist.

I believe it's in this one, if your second part of the code:

await FirebaseFirestore.instance
.collection('users')
.doc(authId)
.collection('cart')
.doc(authId)
.collection('restItemId')
.doc(restItemId)
.get()
  • Make sure that a .doc(restItemId) exists. Double check you are passing .doc() IDs that exists. You will not face any problems creating\setting documents, because Firebase will create them for you, in the structure you specified, even if they don't exist. But it will not get anything that doesn't exist, and will throw the error you are seeing. The first part of your code works because the documents don't exist yet and you create them, the second part you ask firebase for a document that you assume was created, but it wasn't, or perhaps created using an ID you thought you specified, but didn't.

  • Run your function while monitoring Firebase console, and see how the documents and sub-collections are being created, take note of the IDs, and trace it down. I would advise to break up the logic being used to create the entries, because as you may have seen, it's gets pretty tangled to follow, even though it's formatted nicely.

  • The logic for creating a new entry is always the same, so spilt your function into the parts, one that checks if something exists or not, a simple if statemnet asyou used, and based on the condition send them towards the two functions i.e void addNewRestaurant() and void existingRestaurant().

Upvotes: 1

Related Questions