如何在Flutter FirestoreProvider中显示数据

时间:2020-02-25 12:18:01

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

我想在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;
     }); 

    }

    }

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

您永远不会从_getFeaturedProducts()类中调用AppProvider。因此_fearturedProducts将始终为空

答案 2 :(得分:0)

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

_productService.getFeaturedProducts()

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

enter image description here