skip to Main Content

I am retrieving a collection from firebase firestore. and it shows in my app. But when I manually change values in firebase it doesn’t change in my Apps UI in real time. Changes only occur after a hot reload. I am using the Obx method

Here is my modal page

StoreModel storeModelFromJson(String str) => StoreModel.fromJson(json.decode(str));

String storeModelToJson(StoreModel data) => json.encode(data.toJson());

class StoreModel {
    StoreModel({
       required this.image,
       required this.name,
       required this.description,
       required this.type,
    });

    String image;
    String name;
    String description;
    String type;

    factory StoreModel.fromJson(Map<String, dynamic> json) => StoreModel(
        image: json["image"],
        name: json["Name"],
        description: json["description"],
        type: json["type"],
    );

    Map<String, dynamic> toJson() => {
        "image": image,
        "Name": name,
        "description": description,
        "type": type,
    };
}

Here’s my GetxController class

class StoreController extends GetxController{
  
  var storeList = <StoreModel>[].obs;

  @override
  void onInit() {
   
    fetchRecords();
    super.onInit();
  }

  fetchRecords()async{
    var records =await FirebaseFirestore.instance.collection('store_products').get();
    showProducts(records);
  }
   
  showProducts(QuerySnapshot<Map<String,dynamic>> records) {
   var listDb = records.docs.map((item) => StoreModel(
      image:item['Image'], 
      name: item['Name'], 
      description:item['description'], 
      type: item['type']
      )
      ).toList();
 
      if(records != null){
        storeList.value = listDb;
      }
      return storeList;
  }  
}

And below is where I use Obx


Obx(()=> GridView.builder(
  physics: ScrollPhysics(),
  shrinkWrap: true,
  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 2,
    mainAxisSpacing: 10,
    crossAxisSpacing: 10,
    childAspectRatio: 2 / 3),
    itemCount:controller.storeList.length,
    itemBuilder: (BuildContext context, int index) {
      return StoreItemWidget(
        storeItem: controller.storeList[index],
      );
    },
  )
)

2

Answers


  1. I think you need to use storeList.refresh() in your getxcontroller or call update() function.

    Login or Signup to reply.
  2. The issue is that you are using the get function to fetch data from firestore which is a one-time call.

    var records = await FirebaseFirestore.instance.collection('store_products').get();
    

    The get function fetches the values from firebase only once. If you want to update your Ui in real-time as the value change in the firestore then use stream instead of future.

    The snapshot function returns the stream, listening to the stream will update the value as its changes in the firestore.

    FirebaseFirestore.instance.collection('store_products')
            .snapshots()
            .listen((event) {
    
             
            });
    
    

    Here is the full code:

    
    class StoreController extends GetxController {
      final storeList = <StoreModel>[].obs;
    
      @override
      void onInit() {
        super.onInit();
        fetchRecords();
      }
    
      void fetchRecords() {
        List<StoreModel> list = [];
    
        FirebaseFirestore.instance
            .collection('store_products')
            .snapshots()
            .listen((QuerySnapshot<Map<String, dynamic>> event) {
    
          list.clear(); //To avoid duplicating items
    
          for (var item in event.docs) {
    
            StoreModel model = StoreModel(
              image: item.get('Image'),
              name: item.get('Name'),
              description: item.get('description'),
              type: item.get('type'),
            );
    
            list.add(model);
          }
    
          storeList.assignAll(list);
        });
      }
    }
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search