Skip to main content

Command Palette

Search for a command to run...

Simplifying User Authentication in Flutter: A Step-by-Step Guide with Interactive Example

Published
8 min read
Simplifying User Authentication in Flutter: A Step-by-Step Guide with Interactive Example
H

Hello there! My name is Harsh and I am a computer science undergraduate student. From a young age, I have been fascinated by the world of technology and how it impacts our daily lives. As I grew older, my passion for technology only intensified, which led me to pursue a degree in computer science.

During my studies, I have developed a keen interest in the field of mobile app development, particularly in Flutter, a popular framework for building high-quality, native apps for both Android and iOS. I find the process of creating something from scratch, watching it come to life, and then seeing people use it to be an incredibly rewarding experience.

In addition to mobile app development, I have also taken an interest in DevOps, a set of practices that emphasizes collaboration and communication between software developers and IT professionals. The ability to streamline and automate the software development process through DevOps is fascinating to me, and I believe it has the potential to revolutionize the industry.

In addition to my passion for Flutter, DevOps, I have also developed a strong foundation in data structures and algorithms (DSA) using Java. During my high school years, I spent a significant amount of time learning about DSA and applying it to solve complex programming problems. This experience has helped me to build a solid understanding of fundamental programming concepts, and I continue to leverage this knowledge in my current studies.

As a lifelong learner, I am always seeking out new challenges and opportunities to expand my knowledge and skills. One area that has particularly caught my attention is open source software. I find the collaborative nature of open source to be incredibly powerful and inspiring, and I am excited about the potential it has to create positive change in the world.

In my free time, I enjoy exploring new technologies, reading books on various topics, and experimenting with different coding projects. I also enjoy sharing my knowledge and experiences with others, whether it's through mentoring, contributing to online communities, or blogging.

In conclusion, I am a computer science undergraduate student who has a keen interest in Flutter, DevOps, Java programming, and DSA. My experience with these technologies, combined with my passion for open-source, has enabled me to develop a strong foundation in programming and problem-solving skills. I am excited to continue learning and exploring new technologies to build innovative solutions and make a positive impact on society.

Thank you for taking the time to read a little bit about me. I hope to continue growing as a developer, expanding my knowledge, and contributing to the tech community in meaningful ways.

Authentication is a critical component of almost every mobile application, ensuring that users have secure access to their accounts. Implementing authentication in your Flutter app is essential, and Firebase provides a robust set of tools to make this process efficient and secure. In this comprehensive guide, we'll walk you through the entire process of implementing email-based authentication in a Flutter app using Firebase Authentication. We will explain each line of code in detail and provide a deep understanding of the process.

Prerequisites

Before we begin, ensure you have the following prerequisites:

  • Flutter installed on your development machine.

  • A Firebase project created and configured for your Flutter app.

Now, let's dive into each aspect of email authentication and explore the code in detail.

We will cover five main topics:

  1. Setting up Firebase in Flutter.

  2. User Registration with Email and Password.

  3. User Login with Email and Password.

  4. Email Verification.

  5. Password Reset.

  6. User Logout.

Let's get started!

1. Setting up Firebase in Flutter

Before you can start implementing email authentication, you need to set up Firebase in your Flutter project. Follow these steps:

Step 1: Create a Firebase Project

  1. Visit the Firebase Console.

  2. Click on "Add Project" and follow the on-screen instructions to create a new Firebase project.

Step 2: Configure Your App

  1. After creating the project, click on "Add app" and select the appropriate platform (iOS/Android) for your Flutter app.

  2. Follow the setup instructions, including downloading a config file (google-services.json for Android, GoogleService-Info.plist for iOS), and placing it in the appropriate location within your Flutter project.

Step 3: Add Firebase Dependencies

In your Flutter project's pubspec.yaml file, add the following dependencies:

dependencies:
  flutter:
    sdk: flutter
  firebase_core: ^latest_version
  firebase_auth: ^latest_version
  get: ^latest_version # For handling navigation and notifications

Replace ^latest_version with the actual versions of firebase_core, firebase_auth, and get available at the time of implementation. Run flutter pub get to fetch the dependencies.

2. User Registration

User registration is the process of creating a new user account in your app. This is typically the first step for users to access your app's features. Let's break down the code for user registration:

void Signup(String name, String email, String password) async {
  try {
    // Check if the fields are not empty
    if (name.isNotEmpty && email.isNotEmpty && password.isNotEmpty) {
      // Create a new user with Firebase Authentication
      UserCredential userCredential = await FirebaseAuth.instance
          .createUserWithEmailAndPassword(email: email, password: password);
      // Additional actions after successful registration can be added here.
    }
  } catch (e) {
    // Handle registration errors
    log(e.toString());
    Get.snackbar('Error', e.toString());
    Get.offAll(SignUp_Screen());
  }
}

Breaking it down:

  • We begin by defining a function Signup that takes three parameters: name, email, and password.

  • To ensure data integrity, we check if all the required fields are not empty (name.isNotEmpty, email.isNotEmpty, and password.isNotEmpty).

  • We use Firebase Authentication's createUserWithEmailAndPassword method to create a new user account with the provided email and password.

  • After successful registration, you can include additional actions such as sending a verification email or navigating the user to their profile page.

  • In case of any errors during registration, we log the error, display an error message using Get.snackbar, and navigate the user back to the signup screen.

3. User Login

Once users have registered, they need to log in to access their accounts. Here's how the login functionality is implemented:

void login(String email, String password) async {
  try {
    if (email.isNotEmpty && password.isNotEmpty) {
      await FirebaseAuth.instance
          .signInWithEmailAndPassword(email: email, password: password)
          .then((value) {
        if (FirebaseAuth.instance.currentUser!.uid != null) {
          Get.snackbar('Congratulations', "You have logged in successfully");
          Get.offAll(HomeScreen());
        }
      });
    } else {
      Get.snackbar(
          'Incomplete details', 'Please fill all the required fields');
    }
  } catch (e) {
    log(e.toString());
    Get.offAll(Login_Screen());
  }
}

Here's a detailed explanation:

  • The login function takes two parameters: email and password.

  • We begin by checking if both the email and password fields are not empty.

  • We use Firebase Authentication's signInWithEmailAndPassword method to authenticate the user with the provided email and password.

  • Upon successful login, you can perform additional actions, such as displaying a success message using Get.snackbar and navigating the user to the home screen.

  • If the login attempt fails or if there are any errors, we log the error, display an error message, and navigate the user back to the login screen.

4. Email Verification

Email verification adds an extra layer of security to your app by ensuring that users provide a valid email address. It also helps verify the authenticity of user accounts. Here's how you can implement email verification:

Future sendVerificationLink() async {
  try {
    final user = FirebaseAuth.instance.currentUser!;
    await user.sendEmailVerification();
  } catch (e) {
    Get.snackbar('Error', 'Some Error Occurred');
  }
}

Breaking it down step by step:

  • We define a function sendVerificationLink that is marked as async since it involves asynchronous operations.

  • To send a verification link, we first obtain the current user using FirebaseAuth.instance.currentUser.

  • We then use the sendEmailVerification method on the user object to send a verification email.

  • In case of any errors during this process, we display an error message to the user.

5. Password Reset

Allowing users to reset their passwords is a common and essential feature. Here's how you can implement password reset functionality:

static void reset_password(String email) async {
  try {
    await FirebaseAuth.instance.sendPasswordResetEmail(email: email).then(
        (value) => Get.snackbar("Email Sent",
            'Reset password email has been sent to your entered email'));
  } catch (e) {
    log(e.toString());
  }
}

Let's break it down:

  • We define a static function reset_password that takes the user's email as a parameter.

  • To reset a password, we use Firebase Authentication's sendPasswordResetEmail method, passing the user's email.

  • After successfully initiating the password reset process, we display a success message informing the user that an email has been sent to their email address.

  • In case of any errors, we log the error for debugging purposes.

6. Logout

Logout functionality allows users to sign out of their accounts or switch to different accounts. Here's how you can implement user logout:

void logout() async {
  try {
    await FirebaseAuth.instance.signOut().then(
      (value) {
        Get.offAll(const Login_Screen());
      },
    );
    Get.snackbar("Successfully Logout", "");
  } catch (e) {
    print('Error in logging out');
  }
}

Breaking it down:

  • The logout function is defined to handle the user's logout action.

  • We use Firebase Authentication's signOut method to log the user out.

  • After successful logout, we navigate the user to the login screen using Get.offAll.

  • We also display a success message to inform the user that they have been successfully logged out.

  • If any errors occur during the logout process, we print an error message for debugging.

Example: Building a Flutter UI with Email Authentication

Now that we've discussed the code for email-based authentication in detail, let's put it into action by creating a simple Flutter app with a user interface (UI) that incorporates all the functionalities we've covered. This practical section, titled "Example," will demonstrate how to integrate user registration, login, email verification, password reset, and logout into your Flutter app.

Building the User Interface

To begin, we'll create a Flutter app with a basic user interface (UI) that includes input fields for email and password, along with buttons for each functionality. We'll use the Get package for easy navigation and display of snackbars to show messages.

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'Authentication Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: AuthenticationScreen(),
    );
  }
}

class AuthenticationScreen extends StatelessWidget {
  final TextEditingController emailController = TextEditingController();
  final TextEditingController passwordController = TextEditingController();

  void _signup() async {
    try {
      UserCredential userCredential = await FirebaseAuth.instance
          .createUserWithEmailAndPassword(
              email: emailController.text,
              password: passwordController.text);

      // Additional actions after successful registration
      // e.g., sending a verification email or navigating to the home screen
    } catch (e) {
      print(e.toString());
      Get.snackbar('Error', e.toString());
    }
  }

  void _login() async {
    try {
      UserCredential userCredential = await FirebaseAuth.instance
          .signInWithEmailAndPassword(
              email: emailController.text,
              password: passwordController.text);

      // Additional actions after successful login
      // e.g., navigating to the home screen
    } catch (e) {
      print(e.toString());
      Get.snackbar('Error', e.toString());
    }
  }

  void _sendVerificationLink() async {
    try {
      final user = FirebaseAuth.instance.currentUser!;
      await user.sendEmailVerification();
    } catch (e) {
      print(e.toString());
      Get.snackbar('Error', 'Some Error Occurred');
    }
  }

  static void _resetPassword(String email) async {
    try {
      await FirebaseAuth.instance.sendPasswordResetEmail(email: email);
      Get.snackbar("Email Sent",
          'Reset password email has been sent to your entered email');
    } catch (e) {
      print(e.toString());
      Get.snackbar('Error', 'Some Error Occurred');
    }
  }

  void _logout() async {
    try {
      await FirebaseAuth.instance.signOut();
      Get.offAll(LoginScreen());
      Get.snackbar("Successfully Logout", "");
    } catch (e) {
      print('Error in logging out');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Authentication Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            TextFormField(
              controller: emailController,
              decoration: InputDecoration(labelText: 'Email'),
            ),
            TextFormField(
              controller: passwordController,
              decoration: InputDecoration(labelText: 'Password'),
              obscureText: true,
            ),
            SizedBox(height: 16.0),
            ElevatedButton(
              onPressed: _signup,
              child: Text('Sign Up'),
            ),
            ElevatedButton(
              onPressed: _login,
              child: Text('Log In'),
            ),
            ElevatedButton(
              onPressed: _sendVerificationLink,
              child: Text('Send Verification Email'),
            ),
            ElevatedButton(
              onPressed: () {
                _resetPassword(emailController.text);
              },
              child: Text('Reset Password'),
            ),
            ElevatedButton(
              onPressed: _logout,
              child: Text('Logout'),
            ),
          ],
        ),
      ),
    );
  }
}

class LoginScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Login Screen'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('You have successfully logged in!'),
            ElevatedButton(
              onPressed: () {
                // Implement actions to navigate to the home screen
              },
              child: Text('Continue'),
            ),
          ],
        ),
      ),
    );
  }
}

Conclusion

In this extensive guide, we've covered the entire process of implementing email-based authentication in a Flutter app using Firebase Authentication. Each code snippet has been explained in detail to help you understand the logic and functionality behind user registration, login, email verification, password reset, and logout. By following these steps, you can create a robust and secure authentication system for your Flutter app, enhancing user trust and engagement. Firebase Authentication simplifies this process and ensures that your users' data remains secure.

More from this blog

harsh's blog

35 posts