skip to Main Content
void signUserIn() async {

    showDialog(
      context: context,
       builder: (context) {
        return const Center(
          child: CircularProgressIndicator(),
        );
       },
    );


    try {
      await FirebaseAuth.instance.signInWithEmailAndPassword(
        email: emailController.text, 
        password: passwordController.text,
      );
      //pop the loading circle
      Navigator.of(context).pop();
    } on FirebaseException catch (e) {
      //pop the loading circle
      Navigator.of(context).pop();
      if (e.code == 'user-not-found') {
        wrongEmailMessage();
      } else if (e.code == 'wrong-password') {
        wrongPasswordMessage();
      }
    }    
  }

  void wrongEmailMessage() {
      showDialog(
        context: context, 
        builder: (context) {
          return const AlertDialog(
            title: Text('Incorrect Email'),
          );
        },
      );
    }
  
  void wrongPasswordMessage() {
      showDialog(
        context: context, 
        builder: (context) {
          return const AlertDialog(
            title: Text('Incorrect Password'),
          );
        },
      );
    }

Using Navigator.of(context).pop(); to remove the loading circle behaves as expected when clicking my sign in button as normal, but if I spam it, it leads to a black screen. Additionally, VS warns me to not use buildcontext across async methods. Is there a way to stop the double pop or improve my usage?

I tried using Navigator.of(context).pop(); which causes a black screen on spam. I want my loading circle to disappear on auth error, not a black screen.

2

Answers


  1. On the screen when you call function signUserIn, first you must be sure this is StatefullWidget, then you need to add a bool variable to state. Let’s name it _isLoading

    class _PageState extends State<Page> {
    
      bool _isLoading = false;
    
      ...
    }
    

    Then you need to add this code to your function to handle multiple taps

    void signUserIn() async {
     setState(() {
      _isLoading = true;
     });
    
     your code ...
    
     setState(() {
      _isLoading = false;
     });
    

    In your layout, I reccomend you handle _isLoading variable to display CircularProgressIndicator

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Stack(
            children: [
              const Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Text(
                      'Authentication',
                    ),
                  ],
                ),
              ),
              if (_isLoading)
                Container(
                  color: Colors.black.withOpacity(0.5),
                  child: const Center(
                    child: CircularProgressIndicator(),
                  ),
                ),
            ],
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: _isLoading signUserIn,
            tooltip: 'Sign in',
            child: const Icon(Icons.add),
          ),
        );
      }
    

    Now you don’t need to call the pop method to close the dialog with CircularProgressIndicator, so you can remove that code and it will be something like that

    void signUserIn() async {
    
     try {
      await FirebaseAuth.instance.signInWithEmailAndPassword(
        email: emailController.text, 
        password: passwordController.text,
      );
    } on FirebaseException catch (e) {
      if (e.code == 'user-not-found') {
        wrongEmailMessage();
      } else if (e.code == 'wrong-password') {
        wrongPasswordMessage();
      }
    }    
    

    }

    Well, it’s really simple and easy but I think it’s OK for a pet project but not for the production code.

    In the best case, a button should call a state management and then just wait for another state to display. Please, read about state management, it really important part of Flutter applications.

    flutter_bloc

    riverpod

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