I just touch on Flutter recently and I have done CRUD function where I can CRUD user typed strings to Cloud Firestore. I'm now trying to store images in Cloud Firestore. I have looked for some tutorials regarding this but all of them are storing images in Firebase Storage only.
Below is the code I did so far:
Models/Enter.dart
import 'package:flutter/material.dart'; class Enter { final String enterId; final String enter; final String price; Enter({this.enter, this.price, @required this.enterId}); factory Enter.fromJson(Map<String, dynamic> json){ return Enter( enter: json['enter'], price: json['price'], enterId: json['enterId'] ); } Map<String,dynamic> toMap(){ return { 'enter':enter, 'price':price, 'enterId':enterId }; } } Providers/enter_provider.dart
import 'package:flutter/material.dart'; import 'package:ecommerce_int2/models/enter.dart'; import 'package:ecommerce_int2/services/firestore_service2.dart'; import 'package:uuid/uuid.dart'; class EnterProvider with ChangeNotifier { final firestoreService = FirestoreService2(); String _enter; String _price; String _enterId; var uuid = Uuid(); //Getters String get enter => _enter; String get price => _price; Stream<List<Enter>> get enters => firestoreService.getEnter(); //Setters set changeEnter(String enter){ _enter = enter; notifyListeners(); } set changePrice(String price){ _price = price; notifyListeners(); } //Functions loadAll(Enter enter){ if (enter != null && price != null){ _enter =enter.enter; _price =enter.price; _enterId = enter.enterId; } else { _enter = null; _price = null; _enterId = null; } } saveEnter(){ if (_enterId == null){ //Add var newEnter = Enter(enter: _enter, price: _price, enterId: uuid.v1()); print(newEnter.enter); print(newEnter.price); firestoreService.setEnter(newEnter); } else { //Edit var updatedEnter = Enter(enter: _enter, price: _price, enterId: _enterId); firestoreService.setEnter(updatedEnter); } } removeEnter(String enterId){ firestoreService.removeEnter(enterId); } } Services/firestore_service2.dart
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:ecommerce_int2/models/enter.dart'; class FirestoreService2 { FirebaseFirestore _db = FirebaseFirestore.instance; //Get Entries Stream<List<Enter>> getEnter(){ return _db .collection('enters') .snapshots() .map((snapshot) => snapshot.docs .map((doc) => Enter.fromJson(doc.data())) .toList()); } //Upsert Future<void> setEnter(Enter enter){ var options = SetOptions(merge:true); return _db .collection('enters') .doc(enter.enterId) .set(enter.toMap(),options); } //Delete Future<void> removeEnter(String enterId){ return _db .collection('enters') .doc(enterId) .delete(); } } Screens/enter.dart this is where user enter new string, update string and delete string.
import 'package:date_format/date_format.dart'; import 'package:flutter/material.dart'; import 'package:ecommerce_int2/models/enter.dart'; import 'package:ecommerce_int2/providers/enter_provider.dart'; import 'package:provider/provider.dart'; import 'package:device_apps/device_apps.dart'; class EnterScreen extends StatefulWidget { final Enter enter; final Enter price; final Enter category; EnterScreen({this.enter, this.price, this.category}); @override _EnterScreenState createState() => _EnterScreenState(); } class _EnterScreenState extends State<EnterScreen> { final enterController = TextEditingController(); final enterController2 = TextEditingController(); String valueChoose; List listItem = [ "UK", "US" ]; String valueChoose2; List listItem2 = [ "S", "M", "L", "XL" ]; @override void dispose() { enterController.dispose(); enterController2.dispose(); super.dispose(); } @override void initState() { final enterProvider = Provider.of<EnterProvider>(context,listen: false); if (widget.enter != null){ //Edit enterController.text = widget.enter.enter; enterController2.text = widget.enter.price; enterProvider.loadAll(widget.enter); enterProvider.loadAll(widget.price); } else { //Add enterProvider.loadAll(null); } super.initState(); } @override Widget build(BuildContext context) { final enterProvider = Provider.of<EnterProvider>(context); return Scaffold( appBar: AppBar(title: Text('Products')), body: Padding( padding: const EdgeInsets.all(8.0), child: ListView( children: [ TextField( decoration: InputDecoration( labelText: 'Name', border: InputBorder.none, ), style: TextStyle(color: Colors.black, fontSize: 25), maxLines: 5, minLines: 2, onChanged: (String value) => enterProvider.changeEnter = value, controller: enterController, ), TextField( decoration: InputDecoration( labelText: 'Price', border: InputBorder.none, ), style: TextStyle(color: Colors.black, fontSize: 25), maxLines: 5, minLines: 2, onChanged: (String value) => enterProvider.changePrice = value, controller: enterController2, ), Text( 'For product image, please refer to HomePage.', style: TextStyle(fontSize: 15), ), SizedBox( height: 30, ), Padding( padding: const EdgeInsets.fromLTRB(0, 0, 140.0, 0), child: DropdownButton( hint: Text("Select Measurement Standard: "), value: valueChoose, onChanged: (newValue) { setState(() { valueChoose = newValue; }); }, items: listItem.map((valueItem) { return DropdownMenuItem( value: valueItem, child: Text(valueItem), ); }).toList(), ), ), Padding( padding: const EdgeInsets.fromLTRB(0, 0, 250.0, 0), child: DropdownButton( hint: Text("Select Size: "), value: valueChoose2, onChanged: (newValue2) { setState(() { valueChoose2 = newValue2; }); }, items: listItem2.map((valueItem2) { return DropdownMenuItem( value: valueItem2, child: Text(valueItem2), ); }).toList(), ), ), SizedBox( height: 60, ), RaisedButton( color: Theme.of(context).accentColor, child: Text('Add To Cart',style: TextStyle(color: Colors.white, fontSize: 20)), onPressed: () { }, ), RaisedButton( color: Theme.of(context).accentColor, child: Text('Try Out',style: TextStyle(color: Colors.white, fontSize: 20)), onPressed: () => DeviceApps.openApp('com.DefaultCompany.clothestryingfunction2'), ), ], ), ), ); } } Screens/product_view.dart where user gets to see the product list.
import 'package:date_format/date_format.dart'; import 'package:flutter/material.dart'; import 'package:ecommerce_int2/models/enter.dart'; import 'package:ecommerce_int2/providers/enter_provider.dart'; import 'package:ecommerce_int2/screens/enter.dart'; import 'package:provider/provider.dart'; class ProductScreen extends StatelessWidget { @override Widget build(BuildContext context) { final enterProvider = Provider.of<EnterProvider>(context); return Scaffold( appBar: AppBar( title: Text('Products'), ), body: StreamBuilder<List<Enter>>( stream: enterProvider.enters, builder: (context, snapshot) { return ListView.builder( itemCount: snapshot.data.length, itemBuilder: (context, index) { return ListTile( title: Text( snapshot.data[index].enter, style: TextStyle(fontSize: 25), ), subtitle: Text( snapshot.data[index].price, ), onTap: () { Navigator.of(context).push(MaterialPageRoute( builder: (context) => EnterScreen(enter: snapshot.data[index], price: snapshot.data[index]))); }, ); }); }), ); } } I'm wondering how can I CRUD the images in Firebase Storage and get the image url to store in Cloud Firestore at the same time whenever I upload a new image? (Sorry that I'm totally new to Flutter with just a little basic knowledge)
没有评论:
发表评论