I'm currently stuck at where I'm trying to upload image to Firestore Storage and automatically store the image URL to Cloud Firestore. I have tried to manually upload the image to Firebase Storage and pasting the image url to Cloud Firestore then retrieving it to show the image in my app and it works. Heres the coding that I have done so far:
models/enter.dart
class Enter { final String enterId; final String enter; final String price; final String url; Enter({this.enter, this.price, @required this.enterId, this.url}); factory Enter.fromJson(Map<String, dynamic> json){ return Enter( enter: json['enter'], price: json['price'], url: json['url'], enterId: json['enterId'] ); } Map<String,dynamic> toMap(){ return { 'enter':enter, 'price':price, 'url':url, 'enterId':enterId }; } } services/firestore_service2
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:journal_app/src/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(); } } provider/enter_provider.dart
import 'package:flutter/material.dart'; import 'package:journal_app/src/models/enter.dart'; import 'package:journal_app/src/services/firestore_service2.dart'; import 'package:uuid/uuid.dart'; class EnterProvider with ChangeNotifier { final firestoreService = FirestoreService2(); String _enter; String _price; String _enterId; String _url; var uuid = Uuid(); //Getters String get enter => _enter; String get price => _price; String get url => _url; Stream<List<Enter>> get enters => firestoreService.getEnter(); //Setters set changeEnter(String enter){ _enter = enter; notifyListeners(); } set changePrice(String price){ _price = price; notifyListeners(); } set changeUrl(String url){ _url = url; notifyListeners(); } //Functions loadAll(Enter enter){ if (enter != null && price != null){ _enter =enter.enter; _price =enter.price; _url=enter.url; _enterId = enter.enterId; } else { _enter = null; _price = null; _url = null; _enterId = null; } } saveEnter(){ if (_enterId == null){ //Add var newEnter = Enter(enter: _enter, price: _price, url: _url, enterId: uuid.v1()); print(newEnter.enter); print(newEnter.price); print(newEnter.url); firestoreService.setEnter(newEnter); } else { //Edit var updatedEnter = Enter(enter: _enter, price: _price, url: _url, enterId: _enterId); firestoreService.setEnter(updatedEnter); } } removeEnter(String enterId){ firestoreService.removeEnter(enterId); } } screens/enter.dart where user insert product name, price and image
import 'package:date_format/date_format.dart'; import 'package:flutter/material.dart'; import 'package:journal_app/src/models/enter.dart'; import 'package:journal_app/src/providers/enter_provider.dart'; import 'package:provider/provider.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(); @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: 'Product 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: 'Product Price', border: InputBorder.none, ), style: TextStyle(color: Colors.black, fontSize: 25), maxLines: 5, minLines: 2, onChanged: (String value) => enterProvider.changePrice = value, controller: enterController2, ), RaisedButton( color: Theme.of(context).accentColor, child: Text('Save',style: TextStyle(color: Colors.white, fontSize: 20)), onPressed: () { enterProvider.saveEnter(); Navigator.of(context).pop(); }, ), (widget.enter != null) ? RaisedButton( color: Colors.red, child: Text('Delete',style: TextStyle(color: Colors.white, fontSize: 20)), onPressed: () { enterProvider.removeEnter(widget.enter.enterId); Navigator.of(context).pop(); }, ): Container(), ], ), ), ); } } screens/product.dart where this screen show the product name, price and image in listview
import 'package:date_format/date_format.dart'; import 'package:flutter/material.dart'; import 'package:journal_app/src/models/enter.dart'; import 'package:journal_app/src/providers/enter_provider.dart'; import 'package:journal_app/src/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( leading: Image.network( snapshot.data[index].url, width: 100, height: 100, fit: BoxFit.fitWidth, ), trailing: Icon(Icons.edit, color: Theme.of(context).accentColor), 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]))); }, ); }); }), floatingActionButton: FloatingActionButton( child: Icon(Icons.add), onPressed: () { Navigator.of(context) .push(MaterialPageRoute(builder: (context) => EnterScreen())); }, ), ); } } The goal is to upload image to Firebase Storage, storing the image url at the same time when uploading new image.
I need advice for this project.
URLtoCloud Firestore. thats it.