CodeWithMayank

Firebase Authentication Based on Email/password in Flutter

In this tutorial, We learn the process of implementing Firebase Authentication of Email & Password in a Flutter app using the GetX package. GetX is a lightweight and powerful state management library that simplifies code organization and enhances app performance. By the end of this guide, you’ll have a fully functional authentication system integrated with Firebase in your Flutter app.

Step 1: Set Up Firebase Project :

Before we start, make sure you have a Firebase project set up. If you haven’t done this already, head over to this Integrate Firebase Project in Flutter .

Step 2: Add Dependencies :

In your Flutter project’s pubspec.yaml file, add the necessary dependencies for Firebase Authentication and GetX:

dependencies:
  flutter:
    sdk: flutter
  firebase_core: ^1.10.0
  firebase_auth: ^4.5.0
  get: ^4.6.1

Run flutter pub get to install the dependencies.

Step 3: Initialize Firebase

In your Flutter app’s main.dart file, initialize Firebase in the main() function:

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';

import 'app.dart'; // Your app's main widget

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(App());
}

Step 4: Create Authentication Service :

Next, create an authentication Controller that will handle all authentication-related tasks. This Controller will use GetX’s reactive state management to notify listeners when the authentication state changes.

import 'package:get/get.dart';
import 'package:firebase_auth/firebase_auth.dart';

class AuthController extends GetxController {
  final FirebaseAuth _auth = FirebaseAuth.instance;

  Rx<User?> currentUser = Rx<User?>(null);

  @override
  void onInit() {
    super.onInit();
    _auth.authStateChanges().listen((user) {
      currentUser.value = user;
    });
  }

  Future<void> signUp(String email, String password) async {
    try {
      await _auth.createUserWithEmailAndPassword(
        email: email,
        password: password,
      );
    } catch (e) {
      // Handle error
      print("Error signing up: $e");
    }
  }

  Future<void> signIn(String email, String password) async {
    try {
      await _auth.signInWithEmailAndPassword(
        email: email,
        password: password,
      );
    } catch (e) {
      // Handle error
      print("Error signing in: $e");
    }
  }

  Future<void> signOut() async {
    try {
      await _auth.signOut();
    } catch (e) {
      // Handle error
      print("Error signing out: $e");
    }
  }
}

Step 5: Implement Authentication Screens :

Now, create your authentication screens using StatelessWidget . Here’s an example of a signup screen ( I used my custom made TextEditingField() you can use flutter TextFormField() ) :

  • Login Screen :

import 'package:firebase_auth_flutter/controller/auth_controller.dart';
import 'package:firebase_auth_flutter/view/signup_screen.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import 'components/texteditingfield.dart';

class LoginScreen extends StatelessWidget {
  LoginScreen({super.key});
  final AuthController _authController = Get.put(AuthController());
  final formKeyLogin = GlobalKey<FormState>();

  final emailController = TextEditingController();

  final passwordController = TextEditingController();



  bool isValidEmail(String email) {
    final RegExp emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
    return emailRegex.hasMatch(email);
  }

  @override
  Widget build(BuildContext context) {
    final deviceSize = MediaQuery.of(context).size;

    return Scaffold(
      body: SafeArea(
        child: Container(
          padding: const EdgeInsets.symmetric(
            horizontal: 25,
          ),
          child: SingleChildScrollView(
            child: SizedBox(
              width: deviceSize.width,
              height: deviceSize.height - 200,
              child: Form(
                key: formKeyLogin,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Container(
                      width: MediaQuery.of(context).size.width,
                      height: 200,
                      padding: const EdgeInsets.symmetric(
                        vertical: 25,
                        horizontal: 75,
                      ),
                      child: Image.asset('assets/imgs/logo.png'),
                    ),
                    TextEditingField(
                      labelText: 'Email',
                      controller: emailController,
                      inputType: TextInputType.emailAddress,
                      icon: Icons.person,
                      validator: (value) {
                        if (value == null || value.isEmpty) {
                          return 'Please enter an email or phone number';
                        }
                        if (isValidEmail(value)) {
                          return null; // Return null if the input is a valid email
                        }
                       
                        return 'Please enter a valid email';
                      },
                    ),
                    TextEditingField(
                      controller: passwordController,
                      labelText: 'Password',
                      icon: Icons.lock,
                      isPassword: true,
                      validator: (value) {
                        if (value == null || value.isEmpty) {
                          return 'Please enter your password';
                        } else if (value.length < 8) {
                          return "Password shoud be greater then 8 charactors";
                        }
                        // You can add more complex validation logic here, such as checking for a minimum length.
                        return null; // Return null if the input is valid.
                      },
                    ),
                    const SizedBox(
                      height: 25,
                    ),
                    ElevatedButton(
                      child: const Text("Log in"),
                      onPressed: () {
                        // Validate returns true if the form is valid, or false otherwise.
                        if (formKeyLogin.currentState!.validate()) {
                          _authController.signIn(
                            emailController.text,
                            passwordController.text,
                          );
                        }
                      },
                    ),
                    Container(
                      width: deviceSize.width,
                      margin: const EdgeInsets.symmetric(
                        vertical: 7,
                      ),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          const Text("Don't have an acount"),
                          const SizedBox(
                            width: 5,
                          ),
                          GestureDetector(
                            onTap: () {
                              Get.to(
                                () => SignupScreen(),
                              );
                            },
                            child: const Text(
                              "Sign up",
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

  • Registration Screen :

import 'package:firebase_auth_flutter/controller/auth_controller.dart';
import 'package:firebase_auth_flutter/view/signup_screen.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import 'components/texteditingfield.dart';

class RegistrationScreen extends StatelessWidget {
  RegistrationScreen({super.key});
  final AuthController _authController = Get.put(AuthController());
  final formKeyRegistration = GlobalKey<FormState>();

  final emailController = TextEditingController();

  final passwordController = TextEditingController();

  bool isValidEmail(String email) {
    final RegExp emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
    return emailRegex.hasMatch(email);
  }

  @override
  Widget build(BuildContext context) {
    final deviceSize = MediaQuery.of(context).size;

    return Scaffold(
      body: SafeArea(
        child: Container(
          padding: const EdgeInsets.symmetric(
            horizontal: 25,
          ),
          child: SingleChildScrollView(
            child: SizedBox(
              width: deviceSize.width,
              height: deviceSize.height - 200,
              child: Form(
                key: formKeyRegistration,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Container(
                      width: MediaQuery.of(context).size.width,
                      height: 200,
                      padding: const EdgeInsets.symmetric(
                        vertical: 25,
                        horizontal: 75,
                      ),
                      child: Image.asset('assets/imgs/logo.png'),
                    ),
                    TextEditingField(
                      labelText: 'Email',
                      controller: emailController,
                      inputType: TextInputType.emailAddress,
                      icon: Icons.person,
                      validator: (value) {
                        if (value == null || value.isEmpty) {
                          return 'Please enter an email';
                        }
                        if (isValidEmail(value)) {
                          return null; // Return null if the input is a valid email
                        }

                        return 'Please enter a valid email';
                      },
                    ),
                    TextEditingField(
                      controller: passwordController,
                      labelText: 'Password',
                      icon: Icons.lock,
                      isPassword: true,
                      validator: (value) {
                        if (value == null || value.isEmpty) {
                          return 'Please enter your password';
                        } else if (value.length < 8) {
                          return "Password shoud be greater then 8 charactors";
                        }
                        // You can add more complex validation logic here, such as checking for a minimum length.
                        return null; // Return null if the input is valid.
                      },
                    ),
                    const SizedBox(
                      height: 25,
                    ),
                    ElevatedButton(
                      child: const Text("Log in"),
                      onPressed: () {
                        // Validate returns true if the form is valid, or false otherwise.
                        if (formKeyRegistration.currentState!.validate()) {
                          _authController.signUp(
                            emailController.text,
                            passwordController.text,
                          );
                        }
                      },
                    ),
                    Container(
                      width: deviceSize.width,
                      margin: const EdgeInsets.symmetric(
                        vertical: 7,
                      ),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          const Text("Already have an acount"),
                          const SizedBox(
                            width: 5,
                          ),
                          GestureDetector(
                            onTap: () {
                              Get.to(
                                () => SignupScreen(),
                              );
                            },
                            child: const Text(
                              "Login",
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

Conclusion

Congratulations! You successfully implemented Firebase Email & Password Authentication with GetX in your Flutter app.

Scroll to Top