Sign in
Log inSign up

How to make users vote only once in a Voting App

Kobby Discount's photo
Kobby Discount
·May 30, 2020

Hi everyone. Help me on how to make users vote only once in an app using flutter and Firestore as backend? My app demands users to login/register. i have done a that. Now i need users to vote only once and this i am having issues with. Anyone done this before? Anyone willing to help?

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:compuvote/models/finance_model.dart';
import 'package:compuvote/routes/home_page.dart';
import 'package:compuvote/routes/transitionroute.dart';
import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;

class FinanceResult extends StatefulWidget {
  @override
  _FinanceResultState createState() {
    return _FinanceResultState();
  }
}

class _FinanceResultState extends State<FinanceResult> {
  List<charts.Series<Record, String>> _seriesBarData;
  List<Record> mydata;
  _generateData(mydata) {
    _seriesBarData = List<charts.Series<Record, String>>();
    _seriesBarData.add(
      charts.Series(
        domainFn: (Record record, _) => record.name.toString(),
        measureFn: (Record record, _) => record.votes,
        //colorFn: (Record record, _) => record.color,
        id: 'Record',
        data: mydata,
        // Set a label accessor to control the text of the arc label.
        labelAccessorFn: (Record row, _) => '${row.name}: ${row.votes}',
        colorFn: (_, __) => charts.MaterialPalette.cyan.shadeDefault,
        fillColorFn: (_, __) => charts.MaterialPalette.transparent,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Finance Result'),
          leading: IconButton(
            icon: Icon(Icons.home),
            onPressed: () {
              Navigator.push(context, TransitionPageRoute(widget: HomePage()));
            },
          ),
        ),
        body: Container(
          color: Colors.grey.shade100,
          child: _buildBody(context),
        ));
  }

  Widget _buildBody(BuildContext context) {
    return Column(
      children: <Widget>[
        StreamBuilder<QuerySnapshot>(
          stream: Firestore.instance.collection('finance').snapshots(),
          builder: (context, snapshot) {
            if (!snapshot.hasData) {
              return Center(
                child: LinearProgressIndicator(
                  valueColor: AlwaysStoppedAnimation(
                    Theme.of(context).primaryColor,
                  ),
                ),
              );
            } else {
              List<Record> finance = snapshot.data.documents
                  .map((documentSnapshot) =>
                      Record.fromMap(documentSnapshot.data))
                  .toList();
              return _buildChart(context, finance);
            }
          },
        ),
      ],
    );
  }

  Widget _buildChart(BuildContext context, List<Record> recorddata) {
    mydata = recorddata;
    _generateData(mydata);
    return Padding(
      padding: EdgeInsets.all(8.0),
      child: Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height / 1.2,
        child: Center(
          child: Column(
            children: <Widget>[
              /*
             *  Text(
                'Result for Finance',
                style: TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold),
              ),
             * */
              SizedBox(
                height: 10.0,
              ),
              Expanded(
                child: charts.PieChart(
                  _seriesBarData,
                  animate: true,
                  animationDuration: Duration(seconds: 3),
                  //For adding labels to the chart
                  defaultRenderer: new charts.ArcRendererConfig(
                      strokeWidthPx: 2.0,
                      arcWidth: 100,
                      arcRendererDecorators: [
                        // <-- add this to the code
                        charts.ArcLabelDecorator(
                          labelPosition: charts.ArcLabelPosition.auto,
                          labelPadding: 3,
                          showLeaderLines: true,
                          insideLabelStyleSpec: charts.TextStyleSpec(
                            color: charts.Color.white,
                            fontSize: 12,
                          ),
                          outsideLabelStyleSpec: charts.TextStyleSpec(
                            color: charts.Color.black,
                            fontSize: 12,
                          ),
                        ),
                      ]),
                  /*
                  * behaviors: [
                    new charts.DatumLegend(
                      entryTextStyle: charts.TextStyleSpec(
                          color: charts.MaterialPalette.purple.shadeDefault,
                          fontSize: 18),
                    )
                  ],
                  * */
                ),
              ),
              Container(
                width: MediaQuery.of(context).size.width / 3.5,
                height: 1,
                color: Colors.black38,
              ),
              Expanded(
                child: Scaffold(
                  backgroundColor: Colors.grey.shade100,
                  body: _castVote(context),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _castVote(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
      stream: Firestore.instance.collection('finance').snapshots(),
      builder: (context, snapshot) {
        if (!snapshot.hasData)
          return Center(
            child: LinearProgressIndicator(
              valueColor: AlwaysStoppedAnimation(
                Theme.of(context).primaryColor,
              ),
            ),
          );

        return _buildList(context, snapshot.data.documents);
      },
    );
  }

  Widget _buildList(BuildContext context, List<DocumentSnapshot> snapshot) {
    return ListView(
      padding: const EdgeInsets.only(top: 20.0),
      // ignore: missing_return

      children: snapshot.map((data) => _buildListItem(context, data)).toList(),
    );
  }

  Widget _buildListItem(BuildContext context, DocumentSnapshot data) {
    final record = Record.fromSnapshot(data);

    return Padding(
      key: ValueKey(record.name),
      padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
      child: Card(
        elevation: 2,
        child: Container(
          decoration: BoxDecoration(
            border: Border.all(color: Colors.grey.shade100),
            borderRadius: BorderRadius.circular(5.0),
          ),
          child: ListTile(
              title: Text(record.name),
              trailing: Text(record.votes.toString()),
              onTap: () => record.reference.updateData({'votes': record.votes + 1}),
              ),
        ),
      ),
    );
  }
}