Flutter Firebase Authentication with Email and Password (part - I)
Introduction:
Authentication is a major and required function not only in mobile applications but also on websites as well as desktop applications. Thanks to firebase, we can easily implement the authentication with email and password, as well as other social media platforms.
Here, I would explain, how to Login and Signup with an email Id and Password in the flutter application with firebase authentication. Before starting, I must recommend configuring the Firebase project with your Flutter application.
Enable Firebase Authentication :
Firstly, to enable Email/Password authentication on Firebase, we need to open the online firebase console and navigate to the “Authentication” tab. From there, you need to enable the provider you want to use.
(Here, we discuss Email/Password provider)
Setup Authentication Package :
Before starting, firstly install a firebase authentication package in pubsec.yaml
file:
dependencies:
firebase_auth: ^1.1.3 (current version)
for the web application, we have to add a line in web/index.html
file:
<script src="https://www.gstatic.com/firebasejs/8.5.0/firebase-app.js"></script><!--Add this line-->
<script src="https://www.gstatic.com/firebasejs/8.5.0/firebase-auth.js"></script>
Describe a flow of application:
In brief, a particular data is a stream from the authChecker()
, it returns the screen. Furthermore, I describe it in the proper format.
Dive into the code:
Firstly, create some folders and files like this.
lib:
| Service:
| | authService.dart
| Screens:
| | authScreen.dart
| | homeScreen.dart
| main.dart
Further, create auth service in lib/Service/authService.dart
the file:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';class AuthService{
// initialise firebase auth
final FirebaseAuth _initFirebaseAuth = FirebaseAuth.instance;// stream user auth status
Stream<User> get userStatus => _initFirebaseAuth.authStateChanges();// write a function for signup user
Future signinUser(){...}
Future signupUser(){...}
signoutUser(){...};
}
stream<User> get userStatus => _initFirebaseAuth.authStateChanges();
It streams the user auth state from the authentication checker. The authentication checker is to know, the user is already logged in to an application or not.
Now, for the authentication checker write a code inlib/main.dart
the file:
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';void main() {
runApp(MyApp());
}class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Firebase',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: AuthChecker(),
);
}
}//AuthChecker Classclass AuthChecker extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamBuilder(
// stream from AuthService class, and userStatus is a get method
stream: AuthService().userStatus(),
builder:(BuildContext context, AsyncSnapshot<User> snapshot){
//check the connection state with firebase properties.
if(snapshot.connectionState == ConnectionState.active){
//check the uid(user id) is null or not
if(snapshot.data?.uid == null){
//if user not logged in before, compiler redirect AuthScreen
return AuthScreen();
}
else{
//the user was already logged in, compiler redirect HomeScreen
return HomeScreen();
}
}
}
);
}
}
Here is the explanation for theAuthChecker class
. The StreamBuilder
helps us to stream data at some point, and here we stream data from FirebaseAuth.instance.authStateChanges();
. The connection state is used to check internet connection, as well as snapshot.data?.uid == null
this condition check in the snapshot, userId has value or null.
Now, write a function for signinUser()
,signupUser()
, and signoutUser()
in lib/Service/authService.dart
file:
Future signinUser({@required String email, @required String password}) async{
try {
return await _initFirebaseAuth.signInWithEmailAndPassword(email: email, password: password).then((value) => value.user.uid);
} on FirebaseAuthException catch (e) {
return e.code;
}
}
}
In signinUser()
function, define String email, String password
as required. _initFirebaseAuth
is, early initialized variable, and signInWithEmailAndPassword(email:email, password:password)
It is a firebase pre-defined function for authentication.
Note :
.then((value) => value.user.uid)
property is not required. If you don't want to write, it’s still working. This function only returns userId after user Login.
Future signupUser({@required String email, @required String password}) async {
try {
return await _initFirebaseAuth.createUserWithEmailAndPassword(email: email, password: password).then((value) => value.user.uid);
} on FirebaseAuthException catch (e) {
return e.code;
}
}
}
The signupUser()
function’s signature is the same as signupUser()
function, However in the function body part, must change .createUserWithEmailAndPassword()
function.
signoutUser() {
return _initFirebaseAuth.signOut();
}
The signoutUser()
a function used to log out current users.
Design Application:
So far, we have discussed and written firebase functions. Now, we design the user interface. In the first place, we design a basic structure for the login Screen in lib/authScreen.dart
file:
import 'package:flutter/material.dart';class AuthScreen extends StatelessWidget {
TextEditingController _emailController = new TextEditingController();
TextEditingController _passwordController = new TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
padding: EdgeInsets.symmetric(horizontal: 30),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 20),
Text("Email"),
TextField(
controller: _emailController,
),
SizedBox(height: 20),
Text("Password"),
TextField(
controller: _passwordController,
),
SizedBox(height: 20),
Row(
children: [
Expanded(
flex: 1,
child: MaterialButton(
minWidth: double.infinity,
height: 70,
color: Colors.black,
onPressed: () {
var res = AuthService().signinUser(
email: _emailController.text,
password: _passwordController.text);
print(res);
},
child: Text(
"Login",
style: TextStyle(color: Colors.white),
),
),
),
SizedBox(width: 10),
Expanded(
flex: 1,
child: MaterialButton(
minWidth: double.infinity,
height: 70,
color: Colors.black,
onPressed: () {
var res = AuthService().signupUser(
email: _emailController.text,
password: _passwordController.text);
print(res);
},
child: Text(
"SignUp",
style: TextStyle(color: Colors.white),
),
),
),
],
),
],
),
),
);
}
}
The AuthScreen()
widget displays a simple text field without validation, as well as the Login and Signup button for the call function. while the user clicks on a button, onTap
function call method from AuthService
class. After signIn
or SignUp
the user status change and AuthChecker
redirect HomeScreen
widget. For the HomeScreen()
widget write a code in lib/authScreen.dart
file:
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("User Login"),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
AuthService().signoutUser();
},
child: Icon(Icons.logout),
),
);
}
}
In the HomeScreen()
widget show a simple text in the center of the screen, and a floating action button for the call signoutUser()
function from AuthService
class. After signout, AuthChecker
returns another screen.
Conclusion:
In this article, I have explained a User Authentication with Firebase Auth with the demo, you can modify and experiment according to your own, this little introduction was about the User Authentication with Firebase Auth from my side. In the next article, we learned about Email verification, Password reset and changing an email address.
♥️️♥Thank you for reading this article. If you like it don't forget to hit on 👏🏻 clap.