Home > Net >  How to perform calculations on values retrieving from firebase
How to perform calculations on values retrieving from firebase

Time:03-19

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(),
                        ),
                      );
                    },
                  )),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

CodePudding user response:

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
                    ),
                  ),
                ],
              ),
            ),

CodePudding user response:

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