Photo by Andreas Schnabl on Pexels

How to Implement Firebase Email Authentication ?

Binni G. 🎧🦋

--

Introduction

Welcome to the tutorial on Flutter Firebase authentication! In my previous post I have shown the basic setup, how to get started with Firebase by setting up a Firebase Console project, adding dependencies to your Flutter app, and initialising Firebase in your code. If you haven’t read it yet, I highly recommend doing so to gain a better understanding of the basics of Firebase in Flutter.

Check out my previous Tutorial to setup Firebase Project.

In this blog post, we’ll dive deeper into one of the most commonly used authentication methods in mobile app development.

Email authentication using Firebase

Email authentication allows users to sign up and sign in to your app using their email address and a password, which makes it a great option for many apps. We’ll cover the steps needed to implement email authentication in your Flutter app using Firebase and show you how to handle the authentication flow. So, if you’re ready to learn more about this authentication method and how to implement it in your Flutter app, keep reading!

Firebase Email Authentication allows users to sign in with an email and password.

Let’s Get Down to Business

Step #1: Enable Email

Enable Email option in the firebase console.

Step #2: Create auth.dart

In your Flutter app, create a new file called auth.dart and add the following code to create a new user:

import 'package:firebase_auth/firebase_auth.dart';

class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;

// Sign in with email and password
Future<UserCredential?> signInWithEmailAndPassword(
String email, String password) async {
try {
final userCredential = await _auth.signInWithEmailAndPassword(
email: email, password: password);
return userCredential;
} on FirebaseAuthException catch (e) {
if (e.code == 'user-not-found') {
print('No user found for that email.');
} else if (e.code == 'wrong-password') {
print('Wrong password provided for that user.');
}
// Handle other errors
return null;
}
}

// Register with email and password
Future<UserCredential?> registerWithEmailAndPassword(
String email, String password) async {
try {
final userCredential = await _auth.createUserWithEmailAndPassword(
email: email, password: password);
return userCredential;
} on FirebaseAuthException catch (e) {
if (e.code == 'weak-password') {
print('The password provided is too weak.');
} else if (e.code == 'email-already-in-use') {
print('The account already exists for that email.');
}
// Handle other errors
return null;
}
}

// Sign out
Future<void> signOut() async {
await _auth.signOut();
}

// Check if user is authenticated
Stream<User?> get authStateChanges => _auth.authStateChanges();
}

Step #3: Create signin_page.dart

  • In your Flutter app, create a new file called signin_page.dart and add the following code:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';

import 'auth.dart';

class LoginPage extends StatefulWidget {
static const String routeName = '/login';
const LoginPage({super.key});

@override
_LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
final _formKey = GlobalKey<FormState>();
final AuthService _auth = AuthService();
String _email = '';
String _password = '';

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Login / Sign Up'),
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(labelText: 'Email'),
validator: (value) {
if (value!.isEmpty) {
return 'Please enter your email';
}
if (!value.contains('@')) {
return 'Please enter a valid email';
}
return null;
},
onChanged: (value) {
_email = value;
},
),
const SizedBox(height: 16),
TextFormField(
obscureText: true,
decoration: const InputDecoration(labelText: 'Password'),
validator: (value) {
if (value!.isEmpty) {
return 'Please enter your password';
}
return null;
},
onChanged: (value) {
_password = value;
},
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
UserCredential? userCredential = await _auth
.signInWithEmailAndPassword(_email, _password);
}
},
child: const Text('Sign In'),
),
ElevatedButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
UserCredential? userCredential = await _auth
.registerWithEmailAndPassword(_email, _password);
}
},
child: const Text('Sign Up'),
),
],
)
],
),
),
),
),
);
}
}

Step #4: Create home_page.dart

  • In your Flutter app, create a new file called home_page.dart and add the following code:
import 'package:flutter/material.dart';

import 'auth.dart';

class HomePage extends StatelessWidget {
static const String routeName = '/home';

final AuthService _auth = AuthService();

HomePage({super.key});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home Page'),
actions: [
TextButton.icon(
onPressed: () async {
await _auth.signOut();
},
icon: Icon(Icons.person),
label: Text('Logout'),
style: TextButton.styleFrom(primary: Colors.white),
),
],
),
body: Center(
child: Text(
'You are logged in!',
style: TextStyle(fontSize: 24.0),
),
),
);
}
}

Step #5: Add Code in main.dart

  • In your Flutter app, change your main.dart file and add the following code:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:login_authentication_demo/signin_page.dart';

import 'auth.dart';
import 'home_page.dart';

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

class MyApp extends StatelessWidget {
final AuthService _auth = AuthService();

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Firebase Authentication Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: StreamBuilder(
stream: _auth.authStateChanges,
builder: (BuildContext context, AsyncSnapshot<User?> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
}
if (snapshot.hasData) {
return HomePage();
} else {
return const LoginPage();
}
},
),
routes: {
LoginPage.routeName: (BuildContext context) => const LoginPage(),
HomePage.routeName: (BuildContext context) => HomePage(),
},
);
}
}

Voilà, it’s done.

Sign in, sign up page of your app
Logged In State of your app

Thanks For Reading, Follow Me For More.

--

--