skip to Main Content

I have a button in my app, whenever a user clicks on the button in a day, he won’t be able to click on the button again for the whole day, and when he clicks on the button, the button will be inactive all throughout the day and will be active tomorrow. i saved the time and date of users last clicked on firestore but my issues here is when the button is inactive, it also execute, please below is my code, what am i getting wrong here. i will really appreciate any help

@override
  void initState() {
    super.initState();
    _checkButtonStatus();
  }

verifyAccount() async {
  final response = await http.post(
    Uri.parse('http://'),
     headers: {
            "Content-type": "application/x-www-form-urlencoded", 
            "Accept": "application/json",
          },
    
    body:{
       "accountNo": widget.valueAccountNo,
       "accountName": widget.valueAccountName,
       "bankName": widget.valueBankName,
    });
var data = await json.decode(json.encode(response.body));  
 if(data == "Error"){               
        }
        else{
          //Get Your ERROR message's here
      
        }
  }

  Future<void> _checkButtonStatus() async {
      User? user = _auth.currentUser;
    _uid = user!.uid;
    try {
      DocumentSnapshot documentSnapshot =
          await _firestore.collection('Withdrawals').doc(_uid).get();
      if (documentSnapshot.exists) {
        Timestamp lastPressed = documentSnapshot['date'];
        DateTime lastPressedDate = lastPressed.toDate();
        DateTime currentDate = DateTime.now();
        Duration difference = currentDate.difference(lastPressedDate);

        setState(() {
          _isButtonActive = difference.inHours >= 24;
        });
      }
    } catch (e) {
      print("Error checking button status: $e");
    }
  }


Future<void> _handleButtonPress() async {
    try {
      await _firestore.collection('Withdrawals').doc(_uid).set({
        'date': Timestamp.now(),
      });
      setState(() {
        _isButtonActive = false;
      });
    } catch (e) {
      print("Error handling button press: $e");
    }
  }



 child: ElevatedButton(
          child: Text(_isButtonActive ? 'Continue':'Disabled'),
           onPressed: _isButtonActive ? () async {
            await _handleButtonPress();
            verifyAccount();
          } : null,

        ),
It shouldn't verify or go to verifyAccount() method if the button is inactive, please is there anything am missing or am not doing well please
   

2

Answers


  1. My suggestion was to store the state of the button as a Future<bool> and refactor your function _checkButtonStatus() into _getButtonStatus() a function that returns a future value.

    This also removes the problem of calling setState from initState.

    The example below is adapted from the solution shown at: FutureBuilder. It can be copy/pasted and run in a dartpad.

    import 'package:flutter/material.dart';
    
    void main() => runApp(const SimpleApp());
    
    class SimpleApp extends StatelessWidget {
      const SimpleApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: MyButton(),
        );
      }
    }
    
    class MyButton extends StatefulWidget {
      const MyButton({super.key});
    
      @override
      State<MyButton> createState() => _MyButtonState();
    }
    
    class _MyButtonState extends State<MyButton> {
    
      // State of button is stored as a Future<bool>.
      late Future<bool> _isButtonActive;
    
      @override
      void initState() {
        super.initState();
        _isButtonActive = _getButtonStatus();
      }
    
      Future<bool> _getButtonStatus() async {
        // User? user = _auth.currentUser;
        // _uid = user!.uid;
        try {
          // DocumentSnapshot documentSnapshot =
          //     await _firestore.collection('Withdrawals').doc(_uid).get();
          // if (documentSnapshot.exists) {
          //   Timestamp lastPressed = documentSnapshot['date'];
          //   DateTime lastPressedDate = lastPressed.toDate();
          //   DateTime currentDate = DateTime.now();
          //   Duration difference = currentDate.difference(lastPressedDate);
          //   return difference.inHours >= 24;
    
          // For testing: Remove line below
          return Future.delayed(Duration(seconds: 2), () => true);
        } catch (e) {
          debugPrint("Error checking button status: $e");
          return Future<bool>.value(false);
        }
      }
    
      Future<void> _handleButtonPress() async {
        try {
          // await _firestore.collection('Withdrawals').doc(_uid).set({
          //   'date': Timestamp.now(),
          // });
          setState(() {
            _isButtonActive = Future.value(false);
          });
        } catch (e) {
          debugPrint("Error handling button press: $e");
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return FutureBuilder<bool>(
          future: _isButtonActive,
          builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
            debugPrint('building');
            List<Widget> children;
            if (snapshot.hasData) {
              children = <Widget>[
                ElevatedButton(
                    onPressed: snapshot.data! ? _handleButtonPress : null,
                    child: Text(snapshot.data! ? 'Enabled' : 'Disabled')),
              ];
            } else if (snapshot.hasError) {
              children = <Widget>[
                const Icon(
                  Icons.error_outline,
                  color: Colors.red,
                  size: 60,
                ),
                Padding(
                  padding: const EdgeInsets.only(top: 16),
                  child: Text('Error: ${snapshot.error}'),
                ),
              ];
            } else {
              children = const <Widget>[
                SizedBox(
                  width: 60,
                  height: 60,
                  child: CircularProgressIndicator(),
                ),
                Padding(
                  padding: EdgeInsets.only(top: 16),
                  child: Text('Initializing button...'),
                ),
              ];
            }
            return Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: children,
              ),
            );
          },
        );
      }
    }
    
    Login or Signup to reply.
  2. do it like that

    onPressed: _isButtonActive ? () async {
                await _handleButtonPress();
                verifyAccount();
              } :(){},
    

    instead of passing null pass an empty function.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search