Here is the screenshot of my app screen where I am retrieving data from firebase using stream builder:
enter image description here
Now I want to add all the entries in "Cash In" and "Cash Out " and display their sums in the above cards"Cash in hand " and "Today's balance" respectively.
Do I need to create another stream builder or something else?
Here is my code:
class CaShBookRegister extends StatefulWidget {
const CaShBookRegister({Key? key}) : super(key: key);
#override
_CaShBookRegisterState createState() => _CaShBookRegisterState();
}
class _CaShBookRegisterState extends State<CaShBookRegister> {
final _firestore = FirebaseFirestore.instance;
DateTime date = DateTime.now();
late var formattedDate = DateFormat('d-MMM-yy').format(date);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.symmetric(vertical: 18.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(
height: 16.0,
),
Padding(
padding: const EdgeInsets.all(14.0),
child: Row(
children: [
Expanded(
child: ReuseableCard(
textcolour: Colors.white,
buttonColour: Colors.green,
text: "Cash in hand",
),
),
const SizedBox(
width: 8.0,
),
Expanded(
child: ReuseableCard(
buttonColour: Colors.red,
textcolour: Colors.white,
text: "Today's balance",
),
),
],
),
),
StreamBuilder(
stream: _firestore.collection('CASHINCASHOUT').snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return const Text('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return const Text("Loading");
}
if (snapshot.hasData) {
List<DataCell> displayedDataCell = [];
for (var item in snapshot.data!.docs) {
displayedDataCell.add(
DataCell(
Text(
item['DATE'].toString(),
),
),
);
displayedDataCell.add(
DataCell(
Text(
item['CASHIN'].toString(),
style: const TextStyle(color: Colors.green),
),
),
);
displayedDataCell.add(
DataCell(
Text(
item['CASHOUT'].toString(),
style: const TextStyle(color: Colors.red),
),
),
);
}
return FittedBox(
child: DataTable(
columns: const <DataColumn>[
DataColumn(
label: Text(
'Date',
),
),
DataColumn(
label: Text(
'Cash In',
),
),
DataColumn(
label: Text(
'Cash Out',
),
),
],
rows: <DataRow>[
for (int i = 0; i < displayedDataCell.length; i += 3)
DataRow(cells: [
displayedDataCell[i],
displayedDataCell[i + 1],
displayedDataCell[i + 2]
]),
],
),
);
}
return const CircularProgressIndicator();
},
),
const Spacer(),
Padding(
padding: const EdgeInsets.all(14.0),
child: Row(
children: [
Expanded(
child: ReusableButton(
color: Colors.red,
text: "Add Enteries",
onpress: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const CashInCashOut(),
),
);
},
)),
],
),
),
],
),
),
);
}
}
one way to do this is by subscribing to your stream from firestore inside
initState where you can calculate "Cash in hand " and "Today's balance" and substitute into variables with setState.
Then you pass that variables into your widget, whenever that variable is updated, widget will rebuild itself
int _cashInHand = 0;
int _balance = 0;
#override
void initState() {
_firestore.collection('CASHINCASHOUT').snapshots().listen((qs) {
setState(() {
_cashInHand = <calculate cash in hand from snapshots>
_balance = <calculate today's balance from snapshots>
});
});
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
....
Padding(
padding: const EdgeInsets.all(14.0),
child: Row(
children: [
Expanded(
child: ReuseableCard(
textcolour: Colors.white,
buttonColour: Colors.green,
text: _cashInHand.toString(), // <- pass the variable
),
),
const SizedBox(
width: 8.0,
),
Expanded(
child: ReuseableCard(
buttonColour: Colors.red,
textcolour: Colors.white,
text: _balance.toString(), // <- pass the variable
),
),
],
),
),
You probably comes from an hard solid SQL background, because I did and had a huge difficult to understand differences from sql to firebase, so you must think differently.
What I suggest as where I viewed all Firestore YouTube videos (official Chanel) and flutter same, also I did read a lot of official documentation, I can your options are:
A. When storing an new transaction (I am assuming you store every single cacheIn/Out doc), you do calculate the new balance for that date, this way you store that balance as a solid value and just request the result as you want. I think this is the best option for you, and to do that, you can do a transaction to keep things fine like this:
// Run transaction to do all changes at once
FirebaseFirestore.instance
.runTransaction((transaction) async {
// Store you "transaction"
await FirebaseFirestore
.instance
.collection("TRANSACTIONCOLLECTION")
.add(transaction.toJson());
// With your transaction, update your CACHEINCACHEOUT report collection
transaction.update(
// Your CASHINCASHOUT doc reference
await FirebaseFirestore
.instance
.collection('CASHINCASHOUT')
.doc('itemId'),
/// You can use increment do update the value for cache in or cache out,
/// see this example as i increase in transaction.cacheIn
{
'CACHEIN': FieldValue.increment(transaction.cacheIn)
}
)
});
You can learn more about transactions at <(FlutterFire Docs)[https://firebase.flutter.dev/docs/firestore/usage#transactions]>
Also I viewed this entire playlist at least 3 times to calm down my furious SQL mind for 15 years at (Firebase YouTube)[https://www.youtube.com/watch?v=v_hR4K4auoQ&list=PLl-K7zZEsYLluG5MCVEzXAQ7ACZBCuZgZ]
Related
There's a problem which I'm trying to solve, it is displaying data by recently added to Firestore, through Flutter. What can be done in my case?
In React I would achieve this with useState hook, how can this be achieved in Flutter?
I read about .sort(); method, is that a right way of doing this?
Code:
Form.dart
class FormText extends StatelessWidget {
final String _labelText = 'Enter your weight..';
final String _buttonText = 'Save';
final _controller = TextEditingController();
final dateFormat = new DateFormat.yMMMMd().add_jm();
final _collection =
FirebaseFirestore.instance.collection('weightMeasurement');
void saveItemToList() {
final weight = _controller.text;
if (weight.isNotEmpty) {
_collection.add({
'weight': weight,
'time': dateFormat.format(DateTime.now()),
});
} else {
return null;
}
_controller.clear();
}
#override
Widget build(BuildContext context) {
return Row(
children: <Widget>[
Expanded(
child: TextField(
keyboardType: TextInputType.number,
controller: _controller,
decoration: InputDecoration(
labelText: _labelText,
),
),
),
FlatButton(
color: Colors.blue,
onPressed: saveItemToList,
child: Text(
_buttonText,
style: TextStyle(
color: Colors.white,
),
),
),
],
);
}
}
Measurements.dart
class RecentMeasurement {
Widget buildList(QuerySnapshot snapshot) {
return ListView.builder(
reverse: false,
itemCount: snapshot.docs.length,
itemBuilder: (context, index) {
final doc = snapshot.docs[index];
return Dismissible(
background: Container(color: Colors.red),
key: Key(doc.id),
onDismissed: (direction) {
FirebaseFirestore.instance
.collection('weightMeasurement')
.doc(doc.id)
.delete();
},
child: ListTile(
title: Expanded(
child: Card(
margin: EdgeInsets.all(30.0),
child: Column(
children: <Widget>[
Text('Current Weight: ' + doc['weight'] + 'kg'),
Text('Time added: ' + doc['time'].toString()),
],
),
),
),
),
);
},
);
}
}
Layout.dart
class Layout extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(30.0),
child: Column(
children: <Widget>[
FormText(),
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('weightMeasurement')
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return LinearProgressIndicator();
return Expanded(
child: RecentMeasurement().buildList(snapshot.data),
);
}),
],
),
);
}
}
You can try order by . Here is an example
firestoreDb.collection("weightMeasurement")
.orderBy("date", Query.Direction.ASCENDING)
You have to use "orderBy" on your collection, but previously You have to store something called timestamp. Make sure when You upload Your items to Firebase to also upload DateTime.now() along with Your items so You can order them by time. Do not forget to use Ascending direction since it will show you Your items ordered correctly.
I am developing an app, and I want to create a user profile for each logged-in user. With my code now, I am able to get the user information from the cloud Firestore of each user uid document, but I want the user to be able to add an image to firebase storage, and then get this image, add to the specific user uid doc, and display on the app. Basically, I know how to get the data I have already, I just don't know how to update the user doc, especially with images.
Here is the code I have for the user profile:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:tradie_app/scr/providers/authService.dart';
import 'package:tradie_app/scr/screens/edit_company_email.dart';
import 'package:tradie_app/scr/widgets/loading.dart';
import 'home.dart';
class CompanyProfile extends StatefulWidget {
#override
_CompanyProfileState createState() => _CompanyProfileState();
}
class _CompanyProfileState extends State<CompanyProfile> {
// Keep track of the form for validation
final _formKey = GlobalKey<FormState>();
// Loading Icon
bool loading = false;
final AuthService _authService = AuthService();
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
final FirebaseFirestore _firebaseFirestore = FirebaseFirestore.instance;
Future getCompanyNameData() async {
final CollectionReference users =
_firebaseFirestore.collection("Companies");
final String uid = _firebaseAuth.currentUser.uid;
final result = await users.doc(uid).get();
return result.data()["companyName"];
}
Future getCompanyEmailData() async {
final CollectionReference users =
_firebaseFirestore.collection("Companies");
final String uid = _firebaseAuth.currentUser.uid;
final result = await users.doc(uid).get();
return result.data()["companyEmail"];
}
#override
Widget build(BuildContext context) {
return loading
? Loading()
: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
iconTheme: IconThemeData(color: Colors.black),
backgroundColor: Colors.white,
title: Text(
"Create the company profile",
style: TextStyle(
color: Colors.black,
),
),
elevation: 0.0,
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
UserAccountsDrawerHeader(
accountName: FutureBuilder(
future: getCompanyNameData(),
builder: (_, AsyncSnapshot snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Text("Loading");
}
return Text(snapshot.data);
},
),
),
ListTile(
leading: Icon(Icons.logout),
title: Text(
"Log Out",
),
onTap: () async {
await _authService.signOut();
},
),
],
),
),
body: Padding(
padding: const EdgeInsets.all(18.0),
child: SingleChildScrollView(
child: Container(
child: Form(
key: _formKey,
child: Column(
children: [
Row(
children: [
Text(
"Company name: ",
style: TextStyle(
color: Colors.black,
fontSize: 20.0,
),
),
],
),
SizedBox(
height: 10.0,
),
Row(
children: [
FutureBuilder(
future: getCompanyNameData(),
builder: (_, AsyncSnapshot snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Text("Loading");
}
return Text(
snapshot.data,
style: TextStyle(
color: Colors.black, fontSize: 15.0),
);
},
),
],
),
SizedBox(
height: 20.0,
),
Row(
children: [
Text(
"Company email: ",
style: TextStyle(
color: Colors.black,
fontSize: 20.0,
),
),
],
),
SizedBox(
height: 10.0,
),
Row(
children: [
FutureBuilder(
future: getCompanyEmailData(),
builder: (_, AsyncSnapshot snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Text("Loading");
}
return Text(
snapshot.data,
style: TextStyle(
color: Colors.black,
fontSize: 15.0,
),
);
},
),
IconButton(
icon: Icon(Icons.edit),
onPressed: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
EditCompanyEmailScreen(),
),
),
),
],
),
SizedBox(
height: 20.0,
),
Row(
children: [
Text(
"Company phone number: ",
style: TextStyle(
color: Colors.black,
fontSize: 20.0,
),
),
],
),
SizedBox(
height: 20.0,
),
// Here is where I want to add the image
Row(
children: <Widget>[],
),
],
),
),
),
),
),
);
}
}
To select the image from gallery add this plugin. And then call this function to select the image.
File _image;
selectImageFromGallery() async
{
final picker=ImagePicker();
setState(() {
inProcess=true;
});
final imageFile= await picker.getImage(source: ImageSource.gallery);
if(imageFile!=null)
{
_image=File(imageFile.path);
}
setState(() {
inProcess=false;
});
}
after selecting the image run this function to store image to firebase and get url of the image.
Future<String> uploadFile(File image) async
{
String downloadURL;
String postId=DateTime.now().millisecondsSinceEpoch.toString();
Reference ref = FirebaseStorage.instance.ref().child("images").child("post_$postId.jpg");
await ref.putFile(image);
downloadURL = await ref.getDownloadURL();
return downloadURL;
}
now lets upload and update data in firestore docs and storage.
uploadToFirebase()async
{
String url=await uploadFile(_image); // this will upload the file and store url in the variable 'url'
await users.doc(uid).update({ //use update to update the doc fields.
'url':url
});
}
To show the selected image add this in your Ui:-
Container(
height: 200,
width: 200,
decoration: BoxDecoration(image: DecorationImage(image: FileImage(_image,),fit: BoxFit.contain)),
)
After adding this image make a button for upload:-
RaisedButton()
{
onPressed:(){
uploadToFirebase();
},
child:Text("Upload"),
}
After selecting the image user will click on this button to upload and save sata to firebase.
You need to upload the image chosen from gallery to your firebase storage and then use the url in your firestore.
here is a samle code to upload the image to storage
import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;
final ref = firebase_storage.FirebaseStorage.instance.ref().child("profile-pic/abc.jpg");
final imageFile = await ImagePicker.pickImage(source: ImageSource.gallery);
final uploadTask = ref.putFile(imageFile);
final snapshot = await uploadTask.whenComplete(() => null);
imageUrl = await snapshot.ref.getDownloadURL();
use the imageUrl and update it in your firestore collection for the user.
You can fetch the url and display image whenever you need.
I am trying to pass a URL that I receive from Firebase to my NetworkImage widget on the AppBar. However, my code keeps passing a null value to my NetworkImage widget. How can I pass the URL properly to the widget.
class DashboardScreen extends StatefulWidget {
#override
_DashboardScreenState createState() => _DashboardScreenState();
}
class _DashboardScreenState extends State<DashboardScreen> {
Future inputData() async {
final FirebaseAuth auth = FirebaseAuth.instance;
final FirebaseUser user = await auth.currentUser();
final uid = user.uid;
DocumentReference _stock = Firestore.instance.document('users/$uid');
DocumentSnapshot snapshot = await _stock.get();
Map<String, dynamic> data = snapshot.data;
return data['image_url'];
}
String myAvatarUrl;
void converter() {
inputData().then((result) {
myAvatarUrl = result;
print(myAvatarUrl);
});
}
#override
Widget build(BuildContext context) {
converter();
return Scaffold(
appBar: AppBar(
leading: Padding(
padding: EdgeInsets.only(top: 12.0, bottom: 12.0, left: 13.0),
child: CircleAvatar(
backgroundImage: NetworkImage(myAvatarUrl),
child: FlatButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SearchsettingsScreen(),
),
);
},
),
backgroundColor: Colors.white,
),
),
centerTitle: true,
title: Text(
'My Dashboard',
),
backgroundColor: Theme.of(context).primaryColor,
automaticallyImplyLeading: false,
actions: [
DropdownButton(
underline: Container(),
icon: Icon(
Icons.more_vert,
color: Theme.of(context).primaryIconTheme.color,
),
items: [
DropdownMenuItem(
child: Container(
child: Row(
children: <Widget>[
Icon(
Icons.exit_to_app,
),
SizedBox(
width: 8.0,
),
Text('Logout'),
],
),
),
value: 'logout',
),
],
onChanged: (itemIdentifier) {
if (itemIdentifier == 'logout') {
FirebaseAuth.instance.signOut();
}
},
),
],
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
ReusableDashboardSettingCard(),
ReusableDashboardContactsCard(),
],
),
);
}
}
This is the error I get on my console:
The following assertion was thrown building DashboardScreen(dirty, state: _DashboardScreenState#e1615):
'package:flutter/src/painting/_network_image_io.dart': Failed assertion: line 26 pos 14: 'url != null': is not true.
Your main errors are:
you are not managing that there is the possibility that myAvatarUrl can be null
you are not telling to Flutter to rebuild your widget when data will arrive using setState((){})
I suggest you take a look at Codelabs and Fetch data from the internet.
I've not tested it but it should work
import 'package:flutter/material.dart';
class DashboardScreen extends StatefulWidget {
#override
_DashboardScreenState createState() => _DashboardScreenState();
}
class _DashboardScreenState extends State<DashboardScreen> {
String myAvatarUrl;
Future inputData() async {
final FirebaseAuth auth = FirebaseAuth.instance;
final FirebaseUser user = await auth.currentUser();
final uid = user.uid;
DocumentReference _stock = Firestore.instance.document('users/$uid');
DocumentSnapshot snapshot = await _stock.get();
Map<String, dynamic> data = snapshot.data;
return data['image_url'];
}
#override
void initState() {
super.initState();
// When data will arrive
inputData().then((value) {
setState(() => myAvatarUrl = value);
print(myAvatarUrl);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: myAvatarUrl == null
? const SizedBox()
: Padding(
padding: EdgeInsets.only(top: 12.0, bottom: 12.0, left: 13.0),
child: CircleAvatar(
backgroundImage: NetworkImage(myAvatarUrl),
child: FlatButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SearchsettingsScreen(),
),
);
},
),
backgroundColor: Colors.white,
),
),
centerTitle: true,
title: Text(
'My Dashboard',
),
backgroundColor: Theme.of(context).primaryColor,
automaticallyImplyLeading: false,
actions: [
DropdownButton(
underline: Container(),
icon: Icon(
Icons.more_vert,
color: Theme.of(context).primaryIconTheme.color,
),
items: [
DropdownMenuItem(
child: Container(
child: Row(
children: <Widget>[
Icon(
Icons.exit_to_app,
),
SizedBox(
width: 8.0,
),
Text('Logout'),
],
),
),
value: 'logout',
),
],
onChanged: (itemIdentifier) {
if (itemIdentifier == 'logout') {
FirebaseAuth.instance.signOut();
}
},
),
],
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
ReusableDashboardSettingCard(),
ReusableDashboardContactsCard(),
],
),
);
}
}
I have just completed this basic chat app based on a tutorial on YouTube. NO user name needed for using it. But my messages are not ordering correctly. It is sorting as auto generated ID on FireStore. There are total two field in Firebase "message" collection that I have created
"username" {this user name randomly generated by FireBase as user ID. example: 1Mrayhz7EKL7MklHXUxv}
"messagetext"
I don't understanding what should I do now
//Here's the code
class MyApp extends StatelessWidget {
final TextEditingController messaingTextBox = TextEditingController();
final CollectionReference cr =
FirebaseFirestore.instance.collection('messages');
#override
Widget build(BuildContext context) {
body:
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expanded(
child: StreamBuilder(
stream: cr.snapshots(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (!snapshot.hasData) return CircularProgressIndicator();
return ListView.builder(
reverse: true,
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(18.0),
child: Column(
children: [
Row(
children: [
Container(
child: Padding(
padding: const EdgeInsets.all(6.0),
child: Text(
snapshot.data.documents[index]
.data()['username'],
),
),
),
SizedBox(
width: 10,
),
Container(
// width: 38.0,
width: MediaQuery.of(context).size.width / 1.6,
child: Padding(
padding: const EdgeInsets.all(9.0),
child: Column(
children: [
Text(
snapshot.data.documents[index]
.data()['messagetext'],
),
],
),
),
),
],
),
],
),
);
},
);
},
),
),
Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: TextFormField(
cursorColor: HexColor("#003F51"),
style: TextStyle(color: Colors.black),
controller: messaingTextBox,
),
),
),
FloatingActionButton(
onPressed: () {
Message m = Message(
username: "unkown ",
messagetext: messaingTextBox.text.toString());
cr.add(m.mapMessages());
},
child: Icon(Icons.send),
),
],
),
],
);
}
}
class Message {
final String username;
final String messagetext;
Message({this.messagetext, this.username});
mapMessages() {
return {'messagetext': messagetext, 'username': username};
}
}
Please help me for solving this isue
You need to add third field to store time.
Then in the code try to add orderBy operator.
FirebaseFirestore.instance.collection('messages')
.orderBy('time_field', descending: true);
It's quite simple just add a timestamp with each message lets say createdAt, and the use
NOTE: The type of createdAt must be Date
FirebaseFirestore.instance.collection('messages').orderBy('createdAt', descending: true)
How can i show the total amount in the bottom navigation bar... The app uses firebase backend... I have a filed in my database name total price of each item... Now I want to fetch the total price of each item and then add it and display in the bottom navigation bar..
I have attach my firebase backend screen shot.. what i need is to get all the value of the field 'total' add it up and show it in the bottom bar below the Total which is hardcoded as 999 currently section...
It would be helpful if some let me know how to do it.. I am new to app development and flutter as well
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/foundation.dart';
import 'dart:async';
import 'package:fluttertoast/fluttertoast.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final myController = TextEditingController(); ///Alert Dialog box input text myController will be use to store the number of qty
String id;
var qty;
var price;
var total;
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home:Scaffold(
bottomNavigationBar: new Container( //// Bottom Naviagtion Bar for check out and Total price
color: Colors.white,
child: Row(
children: <Widget>[
Expanded(child: ListTile(
title: Text("Total"),
subtitle: Text("Rs 999"),
),),
Expanded(
child: MaterialButton(onPressed:() {},
child: Text("Check Out",style: TextStyle(color: Colors.white),),
color: Colors.red,) ,
)
],
),
),
appBar: AppBar(title: Text('MyKart'),
),
body: (
StreamBuilder(
stream: Firestore.instance.collection('KartDetails').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot kartDetails = snapshot.data.documents[index];
return Container(
height: 150,
child: Card(
elevation: 10,
child: Container(
height: 100,
width: 100,
child: Row(
children: <Widget>[
Container(
width: 100,
height: 100,
child: Image.network(kartDetails['img']),
),
Container(
child: (Text(kartDetails['item'])),
),
Container(
width: 50,
child: (Text('Rs '+kartDetails['price'].toString(),textAlign: TextAlign.end,)),
),
Container(
margin: EdgeInsets.only(left: 20),
height: 120,
width: 50,
color: Colors.white10,
child: Column(
children: <Widget>[
RaisedButton(
color: Colors.grey,
onPressed: (){
showDialog(context: context,
builder: (BuildContext context){
return Dialog(
child: Container(
height: 250,
color: Colors.white10,
child: Container(
margin: EdgeInsets.all(40.0),
child: Column(
children: <Widget>[
TextField(
controller: myController,
keyboardType: TextInputType.number,
decoration: InputDecoration(hintText: 'Enter the Quantity'),
),
Container(
height: 50,
),
RaisedButton(
color: Colors.blue,
child: Text('Submit'),
onPressed: () async{
qty = myController.text;
//==================================================================Total Number of QTY ENTERED==========================================//
if (int.parse(qty)>0 && int.parse(qty)>=5) {
CollectionReference collectionRefernce = Firestore
.instance.collection(
'KartDetails');
QuerySnapshot querySnapshot = await collectionRefernce
.getDocuments();
querySnapshot
.documents[index]
.reference
.updateData(
{"quantity": qty});
//==================================================================Calculate price for each product==========================================//
price = kartDetails['price'];
total=int.parse(qty)*price;
querySnapshot
.documents[index]
.reference
.updateData(
{"total": total});
print(myController
.toString());
Navigator.of(context)
.pop();
myController.clear();
Fluttertoast.showToast(msg: "Quantity Updated",
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 20.0
);
}
else if(int.parse(qty) < 5 || int.parse(qty)<0) {
Fluttertoast.showToast(msg: "Minimum 5 quanity",
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 20.0
);
myController.clear();
}
else {
Fluttertoast.showToast(msg: "Please enter valid quantity",
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 20.0
);
myController.clear();
}
//Firebase query
},
)
],
),
),
),
);
});
},
child: Icon(Icons.shopping_basket),
),
Container(
height: 20,
),
RaisedButton(
color: Colors.grey,
child: Icon(Icons.delete,color: Colors.black87,),
)
],
),
),
Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(left: 3),
height: 50,
width: 70,
child: Center(child: Text('Quantity')),
),
Container(
width: 70,
child: Center(child: Text((kartDetails['quantity']).toString())),
),
Container(
margin: EdgeInsets.only(top: 25),
child: Center(child: Text('Total Price')),),
Container(
margin: EdgeInsets.only(left: 3),
width: 70,
child: Center(child: Text(("Rs " + (kartDetails['total']).toString()))),
),
],
),
],
),
),
),
);
},
);
}
else{
return Center(
child: Container(),
);;
}
},
)
),
),
);
}
}
You can easily do it with this method:
var totalCartValue = 0;
String getCartTotal() async {
QuerySnapshot snapshot = await Firestore.instance
.collection('KartDetails')
.getDocuments();
snapshot.documents.forEach((doc) {
setState((){
totalCartValue += doc.data['total'];
});
});
return totalCartValue.toString();
}
P.S: This method will give you the total of all values in the KartDetails collection not the total for the current user, for the current user it should be like this:
var totalCartValue = 0;
String getCartTotal() async {
QuerySnapshot snapshot = await Firestore.instance
.collection('KartDetails')
.where("UID", isEqualTo: FirebaseAuth.instance.currentUser().toString())
.getDocuments();
snapshot.documents.forEach((doc) {
setState((){
totalCartValue += doc.data['total'];
});
});
return totalCartValue.toString();
}
And use it in the UI that way:
class YourClassName extends StatefulWidget {
#override
_YourClassNameState createState() => _YourClassNameState();
}
class _YourClassNameState extends State<YourClassName> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: //your body code,
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: new Icon(Icons.cart_shopping),
title: new Text(totalCartValue),
),
]
)
);
}
}
You should call it inside your initState so it gets executed whenever app starts:
#override
initState(){
super.initState();
getCartTotal();
}
This is a very vague question, so I will give a shot at one method of solving this. In order to do this you will need some sort of state management solution. I suggest using provider. Flutter has a tutorial on provider here. Essentially you will have to create a ChangeNotifier that every time would onAddItem and onDeleteItem and call notifyListeners() whenever you add or delete items. Then your bottom bar would simply use a Consumer to get the values from your ChangeNotifier. As I said this is just one approach, but since you did not give a replicable example this is the best I can do.