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.