'Suddenly can't fetch any data inside firebase firestore, after trying to use tutorial that contain firestore emulatore

i tried following some of youtube tutorial video and saw a firestore emulators connect. but after i connect the app. the screen that works properly suddenly dont want to fetch list of data from normal firestore. tried to write firebase logout in terminal and still the same. tried flutter clean, and flutter pub get still get the same thing. how can i remove the firestore emulators completely from my app?

enter image description here

this is my product models file

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';

class Product with ChangeNotifier {
  final String id;
  final String title;
  final String description;
  final double price;
  // final String discount;
  final String imageUrl;
  final String productCategoryName;
  final String brand;
  final String userId;
  final String city;
  final int quantity;
  final bool isFavorite;
  final bool isPopular;

  Product({
    required this.id,
    required this.title,
    required this.brand,
    required this.userId,
    required this.description,
    required this.imageUrl,
    required this.isFavorite,
    required this.isPopular,
    required this.price,
    // required this.discount,
    required this.city,
    required this.productCategoryName,
    required this.quantity,
  });
}

class ProductProvider with ChangeNotifier {
  List<Product> _products = [];

  Future<void> fetchProducts() async {
    await FirebaseFirestore.instance
        .collection('products')
        .get()
        .then((QuerySnapshot productSnapshot) {
      _products = [];
      for (var element in productSnapshot.docs) {
        _products.insert(
          0,
          Product(
            // discount: element.get('discount'),
            id: element.get('productId'),
            title: element.get('productTitle'),
            brand: element.get('productBrand'),
            description: element.get('productDescription'),
            imageUrl: element.get('productImage'),
            city: element.get('productCity'),
            price: double.parse(element.get('productPrice')),
            productCategoryName: element.get('productCategory'),
            quantity: int.parse(element.get('productQuantity')),
            userId: element.get('userId'),
            isFavorite: false,
            isPopular: false,
          ),
        );
      }
    });
  }

  List<Product> products() => _products;

  List<Product> getByCatName(String catName) {
    List<Product> catList = _products
        .where((element) =>
            element.productCategoryName.toLowerCase() == catName.toLowerCase())
        .toList();
    return catList;
  }

  List<Product> getByBrandName(String brandName) {
    List<Product> catList = _products
        .where(
            (element) => element.brand.toLowerCase() == brandName.toLowerCase())
        .toList();
    return catList;
  }

  List<Product> get popularProducts {
    return _products.where((element) => element.isPopular).toList();
  }

  Product getById(String prodId) {
    return _products.firstWhere((element) => element.id == prodId);
  }

  Product getBySellerId(String sellerId) {
    return _products.firstWhere((element) => element.userId == sellerId);
  }

  List<Product> getBySellerIds(String sellerId) {
    List<Product> sellerList = _products
        .where(
            (element) => element.userId.toLowerCase() == sellerId.toLowerCase())
        .toList();
    return sellerList;
  }

  List<Product> getBySearch(String search) {
    List<Product> prodList = _products
        .where((element) =>
            element.title.toLowerCase().contains(search.toLowerCase()))
        .toList();
    notifyListeners();
    return prodList;
  }
}

and this is the page/screen that show data using it



class PopularProductMain extends StatelessWidget {
  PopularProductMain({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final productProvider = Provider.of<ProductProvider>(context);
    List<Product> productsList = productProvider.products();
    return Column(
      children: [
        Column(
          children: [
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 8.0),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  const Text(
                    'Suggestion Products',
                    style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600),
                  ),
                  TextButton(
                      onPressed: () {
                        Navigator.of(context).pushNamed(
                          FeedsScreen.routeName,
                          arguments: 'popular',
                        );
                      },
                      child: const Text('view all')),
                ],
              ),
            ),
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 10.0),
              child: SizedBox(
                width: double.infinity,
                child: GridView.builder(
                  padding: EdgeInsets.zero,
                  shrinkWrap: true,
                  physics: const NeverScrollableScrollPhysics(),
                  itemCount: productsList.length,
                  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                      crossAxisCount: 2,
                      childAspectRatio: 175 / 300,
                      mainAxisSpacing: 10,
                      crossAxisSpacing: 10),
                  itemBuilder: (ctx, i) {
                    return ChangeNotifierProvider.value(
                      value: productsList[i],
                      child: const FeedsProduct(),
                    );
                  },
                ),
              ),
            ),
          ],
        ),
      ],
    );
  }
}

and 1 more this is the FeedsProduct.dart


class FeedsProduct extends StatefulWidget {
  const FeedsProduct({Key? key}) : super(key: key);

  @override
  _FeedsProductState createState() => _FeedsProductState();
}

class _FeedsProductState extends State<FeedsProduct> {
  CurrencyFormatter cf = CurrencyFormatter();

  // ignore: non_constant_identifier_names
  CurrencyFormatterSettings IDRSettings = CurrencyFormatterSettings(
    // formatter settings for euro
    symbol: 'Rp',
    symbolSide: SymbolSide.left,
    thousandSeparator: '.',
    decimalSeparator: ',',
  );

  @override
  Widget build(BuildContext context) {
    final productAttribute = Provider.of<Product>(context);

    double discount = 1 / 100;
    double discountPercentage = 1 - (discount * 10);
    double priceAfter = productAttribute.price * discountPercentage;
    // print(priceAfter);

    return InkWell(
      onTap: () {
        Navigator.of(context).pushNamed(ProductDetailsScreen.routeName,
            arguments: productAttribute.id);
      },
      child: Container(
        decoration: BoxDecoration(
          color: Colors.white,
          boxShadow: [
            BoxShadow(
              color: Colors.grey.withOpacity(0.5),
              spreadRadius: 1,
              blurRadius: 5,
              offset: const Offset(0, 3), // changes position of shadow
            ),
          ],
        ),
        child: Column(
          children: [
            Stack(
              children: [
                Column(
                  children: [
                    Positioned(
                      child: SizedBox(
                        height: 210,
                        width: 210,
                        child: FittedBox(
                            clipBehavior: Clip.hardEdge,
                            fit: BoxFit.cover,
                            child: Image.network(productAttribute.imageUrl)),
                      ),
                    ),
                  ],
                ),
              ],
            ),
            Padding(
              padding: const EdgeInsets.only(left: 8, right: 8),
              child: Container(
                width: double.infinity,
                height: 90,
                decoration: const BoxDecoration(
                  color: Colors.white,
                ),
                child: Column(
                  children: [
                    const SizedBox(
                      height: 8,
                    ),
                    Container(
                      alignment: Alignment.centerLeft,
                      child: Text(
                        productAttribute.title,
                        maxLines: 2,
                        style: const TextStyle(
                          fontSize: 15,
                          overflow: TextOverflow.ellipsis,
                        ),
                        textAlign: TextAlign.start,
                      ),
                    ),
                    const Spacer(),
                    Container(
                      alignment: Alignment.centerLeft,
                      child: Text(
                        CurrencyFormatter()
                            .format(productAttribute.price, IDRSettings),
                        maxLines: 1,
                        style: const TextStyle(
                            fontSize: 13,
                            color: Colors.grey,
                            overflow: TextOverflow.ellipsis,
                            decoration: TextDecoration.lineThrough),
                      ),
                    ),
                    Container(
                      alignment: Alignment.centerLeft,
                      child: Text(
                        CurrencyFormatter().format(priceAfter, IDRSettings),
                        maxLines: 1,
                        style: const TextStyle(
                          fontSize: 17,
                          color: Colors.red,
                          overflow: TextOverflow.ellipsis,
                        ),
                      ),
                    ),
                    Padding(
                      padding: const EdgeInsets.only(top: 1),
                      child: Container(
                        alignment: Alignment.centerLeft,
                        child: Text(
                          'Stock ${productAttribute.quantity}',
                          maxLines: 1,
                          style: const TextStyle(
                            fontSize: 12,
                            color: Colors.grey,
                            overflow: TextOverflow.ellipsis,
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.only(left: 5, right: 5),
              child: Container(
                width: double.infinity,
                height: 35,
                decoration: const BoxDecoration(
                  color: Colors.white,
                ),
                child: Column(
                  children: [
                    const Spacer(),
                    Padding(
                      padding: const EdgeInsets.only(top: 1),
                      child: Container(
                        alignment: Alignment.topLeft,
                        child: Row(
                          children: const [
                            Icon(Icons.star, size: 15, color: Colors.amber),
                            Icon(Icons.star, size: 15, color: Colors.amber),
                            Icon(Icons.star, size: 15, color: Colors.amber),
                            Icon(Icons.star, size: 15, color: Colors.amber),
                            Icon(Icons.star_half,
                                size: 15, color: Colors.amber),
                            SizedBox(width: 1),
                            Text(
                              '6 terjual',
                              maxLines: 1,
                              style: TextStyle(
                                fontWeight: FontWeight.w400,
                                fontSize: 12,
                                color: Colors.black,
                                overflow: TextOverflow.ellipsis,
                              ),
                            ),
                          ],
                        ),
                      ),
                    ),
                    Padding(
                      padding: const EdgeInsets.only(top: 2),
                      child: Container(
                        alignment: Alignment.topLeft,
                        child: Row(
                          children: [
                            const Icon(
                              Icons.room_outlined,
                              size: 15,
                              color: Colors.grey,
                            ),
                            Text(
                              productAttribute.city,
                              maxLines: 1,
                              style: const TextStyle(
                                fontWeight: FontWeight.w400,
                                fontSize: 12,
                                color: Colors.grey,
                                overflow: TextOverflow.ellipsis,
                              ),
                            ),
                          ],
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

this is the firebase.json file

{
  "firestore": {
    "rules": "firestore.rules",
    "indexes": "firestore.indexes.json"
  },
  "emulators": {
    "auth": {
      "port": 9098
    },
    "functions": {
      "port": 5002
    },
    "firestore": {
      "port": 8081
    },
    "storage": {
      "port": 9199
    },
    "ui": {
      "enabled": true
    }
  },
  "functions": {
    "source": "functions",
    "predeploy": "npm --prefix \"$RESOURCE_DIR\" run build"
  },
  "storage": {
    "rules": "storage.rules"
  }
}


this is my firebase rules on firestore

service cloud.firestore {   match /databases/{database}/documents {
 match /{document=**} {
   allow read: if auth != null;
   allow write: if auth != null;
 }   } }

tried to find the difference from the previous code on my github extension and didnt found anything suspicious



Solution 1:[1]

This Problem can be resolved by Changing security rules from :

service cloud.firestore {   
match /databases/{database}/documents {
 match /{document=**} {
   allow read: if auth != null;
   allow write: if auth != null;
         }   
     } 
}

To:

rules_version = '2'; 
service cloud.firestore { 
   match /databases/{database}/documents { 
     match /{document=**} { 
        allow read, write: if request.auth != null; 
        }
     } 
  }

And by deactivating AppCheck on your project. AppCheck does not accept all the requests of the Debug mode under the emulator.
To deactivate the AppCheck : Go to the AppCheck window, you'll see the products in which AppCheck is enforced, click on it and then "deactivate". Or you can refer to this thread.

Note : AppCheck is currently in beta, therefore there are lot of issues.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1