【问题标题】:how to display data in flutter firestore provider如何在 Flutter Firestore 提供程序中显示数据
【发布时间】:2020-06-09 04:17:46
【问题描述】:

我想在 Flutter 中使用提供程序显示来自 Firestore 的数据。我被卡住了,请帮忙。以下是我的代码

//产品展示页面

   import 'package:flutter/material.dart';
    import 'package:provider/provider.dart';
    import 'package:shopping/pages/product_details.dart';
    import 'package:shopping/provider/app_provider.dart';
    class Product extends StatefulWidget {
      @override
      _ProductState createState() => _ProductState();
    }

    class _ProductState extends State<Product> {


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


         return GridView.builder(
           itemCount: productList.length,
           gridDelegate:new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount:2),
         itemBuilder: (BuildContext context, int index){

         return Padding(
        padding:const EdgeInsets.all(4.0),
         child:SingleProd(
            //where i want to get the product details 
             prodName: product.featuredProducts[index].name.toString(),

           ),
           );
         }
          );
      }
    }
    class SingleProd extends StatelessWidget {
      final prodName;
      final prodPicture;
      final prodOldPrice;
      final prodPrice;

      SingleProd({this.prodName, this.prodPicture,this.prodOldPrice,this.prodPrice});
      @override
      Widget build(BuildContext context) {
        return Card(
    child: Hero(tag: new Text("hero 1"),
     child:
     Material( child: InkWell(
    onTap: ()=>Navigator.of(context).push(new MaterialPageRoute(builder: (context)=>ProductDetails(
      //here we are passing the value of the products to Product detail page
    productDetailName:prodName,

    )
    )
    ),
     child:GridTile(
    footer: Container(
      color: Colors.white,
      child: new Row(
        children: <Widget>[
          new Expanded(
            child: new Text(prodName, style: TextStyle(fontWeight: FontWeight.bold, fontSize:16.0),),
          ),
          new Text(
            "\$$prodPrice", style: TextStyle(color: Colors.red, fontWeight: FontWeight.bold),)
        ],
      )
    ),
     child: Image.asset(prodPicture, 
       fit: BoxFit.cover,),
     ),
     ),
    ),
    ),
        );
      }



    }

//产品类

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/foundation.dart';
class Product{
  static const ID = "id";
  static const CATEGORY = "category";
  static const NAME = "name";
  static const PRICE = "price";
  static const BRAND = "brand";
  static const COLORS = "colors";
  static const QUANTITY = "quantity";
  static const SIZES = "sizes";
  static const SALE = "sale";
  static const FEATURED = "featured";
  static const PICTURE = "picture";


  String _id;
  String _name;
  String _brand;
  String _category;
  String _picture;
  double _price;
  int _quantity;
  List _colors;
  List _sizes;
  bool _onSale;
  bool _featured;

//  getters
  String get name => _name;
  String get id => _id;
  String get category => _category;
  String get brand => _brand;
  String get picture => _picture;
  double get price => _price;
  int get quantity => _quantity;
  List get colors => _colors;
  List get sizes => _sizes;
  bool get onSale => _onSale;
  bool get featured => _featured;

//  named constructure
  Product.fromSnapshot(DocumentSnapshot snapshot){
    Map data = snapshot.data;
    _name = data[NAME];
    _id = data[ID];
    _category = data[CATEGORY];
    _brand = data[BRAND];
    _price = data[PRICE];
      _quantity = data[QUANTITY];
    _colors = data[COLORS];
    _onSale = data[SALE];
    _featured = data[FEATURED];
    _picture = data[PICTURE];
  }

} 

//产品的供应商页面

     import 'package:flutter/material.dart';
    import 'package:shopping/db/product.dart';
    import 'package:shopping/models/product.dart';

     class AppProvider with ChangeNotifier {
       List<Product>_fearturedProducts=[];
       //method
       void _getFeaturedProducts()async{

        _fearturedProducts=await _productService.getFeaturedProducts();
        notifyListeners();
       }
     }

//连接到 Firestore 以收集数据

    import 'package:cloud_firestore/cloud_firestore.dart';
    import 'package:shopping/models/product.dart';

    class ProductService{
        Firestore _firestore=Firestore.instance;
      String collection="Products";

      Future<List<Product>>getFeaturedProducts(){

     _firestore.collection(collection).where('featured', isEqualTo:true).getDocuments()
     .then((snap){

      List<Product>featuredProducts=[];
       snap.documents.map((snapshot)=> featuredProducts.add(Product.fromSnapshot(snapshot)));
       return featuredProducts;
     }); 

    }

    }

【问题讨论】:

    标签: flutter google-cloud-firestore flutter-provider


    【解决方案1】:

    你永远不会从你的 AppProvider 类中调用 _getFeaturedProducts()。所以_fearturedProducts 将永远为空

    【讨论】:

    • 如何调用 _getFeaturedProducts() 请帮忙
    • 这是你自己的代码,你需要从firebase获取结果才能构建网格
    【解决方案2】:

    在 AppProvider 类中,您正在调用未定义名称的方法:

    _productService.getFeaturedProducts()
    

    每个 IDE 都应该向您显示此错误。在我的 Android Studio 中,它看起来像这样:

    【讨论】:

      【解决方案3】:

      伙计们,我已经设法解决了这个问题。答案如下 //产品页面

      import 'package:cloud_firestore/cloud_firestore.dart';
      import 'package:flutter/material.dart';
      import 'package:provider/provider.dart';
      import 'package:shopping/pages/product_details.dart';
      import 'package:shopping/provider/app_provider.dart';
      import 'package:shopping/models/product.dart';
      class Products extends StatefulWidget {
        @override
      ProductsState createState() => ProductsState();
      }
      
      class ProductsState extends State<Products> {
        List<Product> products;
        @override
        Widget build(BuildContext context) {
      
          final productProvider = Provider.of<CRUDModel>(context);
          return  StreamBuilder<QuerySnapshot>(
                  stream: productProvider.fetchProductsAsStream(),
                  builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
                    if (snapshot.hasData) {
                      products = snapshot.data.documents
                          .map((doc) => Product.fromMap(doc.data, doc.documentID))
                          .toList();
      
           return GridView.builder(
             itemCount: products.length,
             gridDelegate:new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount:2),
           itemBuilder: (BuildContext context,  index){
      
           return Padding(
          padding:const EdgeInsets.all(4.0),
           child:SingleProd(
               product:products[index]
              // prodPicture: productList[index]['picture'],
               //prodOldPrice: productList[index]['oldPrice'],
               //prodPrice: productList[index]['price'],
             ),
             );
           }
            );
            }
           else {
                      return Text('fetching');
                    }
        }
      
        );
      
        }
      
      
      }
      class SingleProd extends StatelessWidget {
       //final prodName;
        //final prodPicture;
        //final prodOldPrice;
        //final prodPrice;
          final Product product;
      
        SingleProd({ @required this.product});
      
      
        //SingleProd({product.picture});
        @override
        Widget build(BuildContext context) {
          return Card(
      child: Hero(tag: product.id,
       child:
       Material( child: InkWell(
      onTap: ()=>Navigator.of(context).push(new MaterialPageRoute(builder: (context)=>ProductDetails(
        //here we are passing the value of the products to Product detail page
      productDetailName:product.name,
      productDetailNewPrice:product.price,
      productDetailPicture:product.picture,
      //productDetailOldPrice:prodOldPrice,
      //productDetailNewPrice:prodPrice,
      //productDetailPicture: prodPicture,
      )
      )
      ),
       child:GridTile(
      footer: Container(
        color: Colors.white,
        child: new Row(
          children: <Widget>[
            new Expanded(
              child: new Text(product.name, style: TextStyle(fontWeight: FontWeight.bold, fontSize:16.0),),
            ),
            new Text(
              '${product.price} \$', style: TextStyle(color: Colors.red, fontWeight: FontWeight.bold),)
          ],
        )
      ),
       child: Image.asset('assets/${product.picture}.jpg',
      
         fit: BoxFit.cover,),
       ),
       ),
      ),
      ),
      
          );
        }
      }   
      

      //产品类

      import 'package:cloud_firestore/cloud_firestore.dart';
      
      import 'dart:ui';
      
      class Product {
        String id;
        String name;
        String brand;
        String category;
        String picture;
        double price;
        int quantity;
        List colors;
        List sizes;
        bool sale;
        bool featured;
      
        Product(
          {this.id, this.name, this.brand, 
          this.category, this.picture,this.price,
           this.quantity,this.colors,this.sizes,this.sale,this.featured}
          );
      
        Product.fromMap(Map snapshot,String id) :
              id = id ?? '',
              name= snapshot['name'] ?? '',
              brand = snapshot['brand'] ?? '',
              category = snapshot['category'] ?? '',
              picture= snapshot['picture'] ?? '',
              price= snapshot['price'] ?? '',
              quantity= snapshot['quantity'] ?? '',
              colors= snapshot['colors'] ?? '',
              sizes= snapshot['sizes'] ?? '',
              sale= snapshot['sale'] ?? '',
              featured= snapshot['featured'] ?? '';
      
      
      
        toJson() {
          return {
            "name": name,
            "brand": brand,
            "category": category,
            "picture": picture,
            "price": price,
            "quantity": quantity,
            "colors": colors,
            "sizes": sizes,
            "sale": sale,
            "featured": brand,
          };
        }
      }
      

      //产品的提供者类

       import 'package:cloud_firestore/cloud_firestore.dart';
      import 'package:shopping/db/Api.dart';
      import 'package:shopping/models/product.dart';
      
      
       class CRUDModel extends ChangeNotifier {
      
        //Api _api = locator<Api>();
      String path="Products";
        Api _api= Api();
      
        List<Product> products;
      
      
        Future<List<Product>> fetchProducts() async {
          var result = await _api.getDataCollection();
          products = result.documents
              .map((doc) => Product.fromMap(doc.data, doc.documentID))
              .toList();
              notifyListeners();
          return products;
        }
      
        Stream<QuerySnapshot> fetchProductsAsStream() {
          notifyListeners();
          return _api.streamDataCollection();
        }
      
        Future<Product> getProductById(String id) async {
          var doc = await _api.getDocumentById(id);
          notifyListeners();
          return  Product.fromMap(doc.data, doc.documentID) ;
        }
      
      }
      

      //连接到firestore

      import 'package:cloud_firestore/cloud_firestore.dart';
      
      class Api{
        final Firestore _db = Firestore.instance;
        String ref="Products";
       //CollectionReference ref;
      
        /*Api({this.path } ) {
          ref = _db.collection(path);
        }*/
      
        Future<QuerySnapshot> getDataCollection() {
          //return ref.getDocuments() ;
      
         return  _db.collection(ref).where('featured', isEqualTo:true).getDocuments();
      
        }
        Stream<QuerySnapshot> streamDataCollection() {
         // return ref.snapshots() ;
        //return _db.snapshots(ref).getDocuments();
        return _db.collection(ref).snapshots();
        }
        Future<DocumentSnapshot> getDocumentById(String id) {
         // return ref.document(id).get();
         return _db.document(id).get();
        }
        Future<void> removeDocument(String id){
          //return ref.document(id).delete();
          return _db.document(id).delete();
        }
        Future<DocumentReference> addDocument(Map data) {
         // return ref.add(data);
         return _db.collection(ref).add(data);
        }
        Future<void> updateDocument(Map data , String id) {
          //return ref.document(id).updateData(data) ;
          return _db.document(ref).updateData(data);
        }
      
      
      }
      

      //我展示产品的主页

      import 'package:flutter/material.dart';
      import 'package:carousel_pro/carousel_pro.dart';
      import 'package:firebase_auth/firebase_auth.dart';
      import 'package:shopping/commons/common.dart';
      import 'package:provider/provider.dart';
      import 'package:shopping/provider/app_provider.dart';
      import '../provider/user_provider.dart';
      
      //My packages imports
      import 'package:shopping/componets/horizontal_listview.dart';
      import 'package:shopping/componets/product.dart';
      import 'package:shopping/pages/cart.dart';
      import 'package:shopping/pages/login.dart';
      
      class HomePage extends StatefulWidget {
         // List<Product> products;
      
        @override
        _HomePageState createState() => _HomePageState();
      }
      
      class _HomePageState extends State<HomePage> {
        TextEditingController _searchController = new TextEditingController();
      
        //final FirebaseAuth _firebaseAuth=FirebaseAuth.instance;
      
        @override
        Widget build(BuildContext context) {
         final user = Provider.of<UserProvider>(context);
         final productProvider=Provider.of<CRUDModel>(context);
          Widget image_carousel = new Container(
            height: 200.0,
            child: new Carousel(
              boxFit: BoxFit.cover,
              images: [
                AssetImage('images/c1.jpg'),
                AssetImage('images/m1.jpeg'),
                AssetImage('images/m2.jpg'),
                AssetImage('images/w1.jpeg'),
                AssetImage('images/w3.jpeg'),
                AssetImage('images/w4.jpeg'),
              ],
              autoplay:true,
              animationCurve: Curves.fastOutSlowIn,
              animationDuration: Duration(milliseconds:1000 ),
              dotSize: 4.0,
              indicatorBgPadding: 8.0,
              dotBgColor: Colors.transparent,
            ),
          );
          return Scaffold(
            appBar: new AppBar(
              iconTheme: IconThemeData(color: blue),
              elevation: 0.1,
              backgroundColor: white,
              title: Material(
                borderRadius: BorderRadius.circular(20),
                color: Colors.grey[50],
                elevation: 0.0,
                child: TextFormField(
                    controller: _searchController,
                    decoration: InputDecoration(
                      hintText: "Search",
                      border: InputBorder.none,
                    ),
                    validator: (value) {
                      if (value.isEmpty) {
                        return "The Search field  cannot be empty";
                      }
                      return null;
                    }),
              ),
              actions: <Widget>[
                new IconButton(
                  icon: Icon(
                    Icons.search,
                    color: blue,
                  ),
                  onPressed: () {},
                ),
                new IconButton(
                    icon: Icon(
                      Icons.shopping_cart,
                      color: blue,
                    ),
                    onPressed: () {
                      Navigator.push(context,
                          MaterialPageRoute(builder: (context) => new Cart()));
                    }),
              ],
            ),
            drawer: new Drawer(
              child: new ListView(
                children: <Widget>[
                  //drawer header
                  new UserAccountsDrawerHeader(
                    accountName: Text("Afolabi"),
                    accountEmail: Text("mtreal62@gmail.com"),
                    currentAccountPicture: GestureDetector(
                      child: new CircleAvatar(
                        backgroundColor: Colors.grey,
                        child: Icon(
                          Icons.person,
                          color: Colors.white,
                        ),
                      ),
                    ),
                    decoration: BoxDecoration(
                      color: blue,
                    ),
                  ),
                  //body
                  InkWell(
                    onTap: () {},
                    child: ListTile(
                      title: Text("Home Page"),
                      leading: Icon(
                        Icons.home,
                        color: blue,
                      ),
                    ),
                  ),
                  InkWell(
                    onTap: () {},
                    child: ListTile(
                      title: Text("My Account"),
                      leading: Icon(
                        Icons.person,
                        color: blue,
                      ),
                    ),
                  ),
                  InkWell(
                    onTap: () {},
                    child: ListTile(
                      title: Text("My Orders"),
                      leading: Icon(
                        Icons.shopping_basket,
                        color: blue,
                      ),
                    ),
                  ),
                  InkWell(
                    onTap: () {
                      Navigator.push(context,
                          MaterialPageRoute(builder: (context) => new Cart()));
                    },
                    child: ListTile(
                      title: Text("Shopping Cart"),
                      leading: Icon(
                        Icons.shopping_cart,
                        color: blue,
                      ),
                    ),
                  ),
                  InkWell(
                    onTap: () {},
                    child: ListTile(
                      title: Text("Favourites"),
                      leading: Icon(
                        Icons.favorite,
                        color: blue,
                      ),
                    ),
                  ),
                  Divider(),
                  InkWell(
                    onTap: () {},
                    child: ListTile(
                      title: Text("Settings"),
                      leading: Icon(
                        Icons.settings,
                      ),
                    ),
                  ),
                  InkWell(
                    onTap: () {},
                    child: ListTile(
                      title: Text("About"),
                      leading: Icon(
                        Icons.help,
                      ),
                    ),
                  ),
      
                  InkWell(
                    onTap: () {
                     user.signOut();
              // changeScreenReplacement(context, Login());
                    },
                    child: ListTile(
                      title: Text("Log Out"),
                      leading: Icon(
                        Icons.transit_enterexit,
                      ),
                    ),
                  ),
                ],
              ),
            ),
            body: new Column(
              children: <Widget>[
                //Image Carousel for the home Page Banner
                image_carousel,
                //padding widget after carousel
                new Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Container(
                    alignment: Alignment.centerLeft,
                    child: new Text("Categories"),
                  ),
                ),
                //Horizontal layout start from here
                HorizontalList(),
                //End of the horizontal layout
      
                //padding widget for Recent products categories
                new Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Container(
                    alignment: Alignment.centerLeft,
                    child: new Text("Recent Products"),
                  ),
                ),
                    // Text(appProvider.featuredProducts.length.toString(),
                       //style: TextStyle(color: Colors.black),),
      
                Flexible(
                  child: Products(),
                ),
                //Horizontal layout start from here
              ],
            ),
          );
        }
      }
      
      Future _signOut() async {
        try {
          await FirebaseAuth.instance.signOut();
        } catch (e) {
          print(e); // TODO: show dialog with error
        }
      }
      

      【讨论】:

        猜你喜欢
        • 2023-03-16
        • 2020-01-14
        • 1970-01-01
        • 2018-11-22
        • 2020-05-11
        • 1970-01-01
        • 2021-11-28
        • 1970-01-01
        • 2022-11-09
        相关资源
        最近更新 更多