How to show loading spinner in the button when sign in using firebase

Viewed 64

i have create a variable "isLoading" for calling the loader. the actual problem is when i hit simply in the "signIn" button without give any value in the test field, it will start loading for delay time how can i stop this and also catch the error when hit the "signIn" button without given any value.... this is my Repo: food delivery app

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import '../../config/constants.dart';

class LoginScreen extends StatefulWidget {
  const LoginScreen({Key? key}) : super(key: key);

  @override
  State<LoginScreen> createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  final emailController = TextEditingController();
  final passwordController = TextEditingController();
  @override
  void dispose() {
    emailController.dispose();
    passwordController.dispose();

    super.dispose();
  }

  bool isLoading = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        padding: const EdgeInsets.all(20),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            const Text('login'),
            htspace20,
            TextField(
              controller: emailController,
              decoration: const InputDecoration(
                border: OutlineInputBorder(),
                label: Text('Email'),
              ),
            ),
            htspace20,
            TextField(
              controller: passwordController,
              decoration: const InputDecoration(
                border: OutlineInputBorder(),
                label: Text('Password'),
              ),
            ),
            htspace40,
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                TextButton(onPressed: () {}, child: const Text('Sign up'))
              ],
            ),
            SizedBox(
              width: double.maxFinite,
              height: 40,
              child: ElevatedButton(
                  style: ButtonStyle(
                    elevation: MaterialStateProperty.all(0),
                  ),
                  child: isLoading
                      ? const SizedBox(
                          height: 30,
                          width: 30,
                          child: CircularProgressIndicator(
                              strokeWidth: 3, color: Colors.white),
                        )
                      : const Text('Sign in'),
                  onPressed: () {
                    setState(() {
                      isLoading = true;
                    });
                    signIn();
                    Future.delayed(const Duration(seconds: 3), () {
                      setState(() {
                        if (emailController.text != " " ||
                            passwordController.text != " ") {
                          isLoading = false;
                        } else {
                          isLoading = true;
                        }
                      });
                    });
                  }),
            )
          ],
        ),
      ),
    );
  }

  Future signIn() async {
    try {
      await FirebaseAuth.instance.signInWithEmailAndPassword(
        email: emailController.text.trim(),
        password: passwordController.text.trim(),
      );
    } catch (e) {
      print('Email or Password Incorrect');
    }
  }
}
2 Answers

Why not try it all in your singIn() function like this:

Future signIn() async {
    try {
      isLoading = true;
      await FirebaseAuth.instance.signInWithEmailAndPassword(
        email: emailController.text.trim(),
        password: passwordController.text.trim(),
      );
      isLoading = false;
    } catch (e) {
      isLoading = false;
      print('Email or Password Incorrect');
    }
  }

This way it will stop loading if email or pass is incorrect or missing etc. I'd also disable the login button if email and pass isn't filled out. Stop them from passing blank values.

ElevatedButton(
                      style: ElevatedButton.styleFrom(
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(20), // <-- Radius
                        ),
                      ),
                      child: isLoading
                          ? const SizedBox(
                              height: 30,
                              width: 30,
                              child: CircularProgressIndicator(
                                  strokeWidth: 3, color: Colors.white),
                            )
                          : const Text('Sign in'),
                      onPressed: () {
                        setState(() {
                          isLoading = true;
                        });
                        signIn();
                        Future.delayed(const Duration(seconds: 3), () {
                          setState(() {
                            if (emailController.text != " " ||
                                passwordController.text != " ") {
                              isLoading = false;
                            } else {
                              isLoading = true;
                            }
                          });
                        });
                      }),

it also showing circular loading on the button

Related