Flutter Login UI with Firebase

We will walk you through designing a Login UI in Flutter in this tutorial.

Flutter N Firebase
7 min readMar 3, 2023

In this section, we’ll go through the fundamental design ideas behind a login page, including how to lay out the screen, add text fields for user input, and add buttons for login and registration. You will have the knowledge and abilities required to build a straightforward yet useful Login UI for your Flutter app at the conclusion of this course. So let’s get going!

Open VScode, then use the terminal to create an app.

flutter samplelogin

After creating flutter app follow the steps to create login UI

main.dart

Open the lib folder and create another folder of pages and create a splashscreen.dart in the pages folder.

splashscreen.dart

Now Write Down the Below Code to Create SplashScreen() with help of Getx and Below SplashService code to navigate from one page to another and Set CurretUser state of user from Firebase.

Before Create SplashScreen Lets Create Custom Button and Toast Message to display message.

Create Button.dart

import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter/src/widgets/placeholder.dart';

class RoundButton extends StatelessWidget {
final String title;
final VoidCallback onTap;
final bool loading;

const RoundButton(
{super.key,
required this.title,
required this.onTap,
this.loading = false});

@override
Widget build(BuildContext context) {
return InkWell(
onTap: onTap,
child: Container(
height: 50,
width: 150,
decoration: BoxDecoration(
color: Colors.indigo, borderRadius: BorderRadius.circular(10)),
child: Center(
child: loading
? CircularProgressIndicator(
strokeWidth: 3,
color: Colors.white,
)
: Text(
title,
style: TextStyle(color: Colors.white),
),
),
),
);
}
}

Now create Utils.dart

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

class Utils {
void toastMessage(String message) {
Fluttertoast.showToast(
msg: message,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
backgroundColor: Colors.indigo,
textColor: Colors.white,
fontSize: 16.0);
}
}

SplashService.dart

import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:login/pages/home.dart';

import 'login.dart';

class SplashServices {
void isLogin(BuildContext) {
final auth = FirebaseAuth.instance;
final user = auth.currentUser;

if (user != null) {
Timer(Duration(seconds: 3), () {
Get.to(() => HomeScreen());
});
} else {
Timer(Duration(seconds: 3), () {
Get.to(() => LoginScreen());
});
}
}
}

SplashScreen.dart with help of Getx.

import 'package:flutter/material.dart';
import 'package:login/pages/splashservices.dart';

class SplashScreen extends StatefulWidget {
const SplashScreen({super.key});

@override
State<SplashScreen> createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen> {
SplashServices splashScreen = SplashServices();

@override
void initState() {
// TODO: implement initState
super.initState();
splashScreen.isLogin(context);
}

@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.indigo,
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
// ignore: prefer_const_literals_to_create_immutables
children: [
Center(
child: Text(
'Flutter Login Tutorials',
style: TextStyle(fontSize: 30, color: Colors.white),
))
],
),
);
}
}

Now Create LoginScreen() with Firebase With Getx to navigate from one page to another.


// ignore_for_file: prefer_const_constructors

import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:login/pages/button.dart';
import 'package:login/pages/signup.dart';
import 'package:login/pages/utils.dart';

import 'forget.dart';
import 'home.dart';

class LoginScreen extends StatefulWidget {
const LoginScreen({super.key});

@override
State<LoginScreen> createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
bool loading = false;
final emailcontroller = TextEditingController();
final passwordcontroller = TextEditingController();

final _formkey = GlobalKey<FormState>();

FirebaseAuth _auth = FirebaseAuth.instance;

@override
void dispose() {
// TODO: implement dispose
super.dispose();
emailcontroller.dispose();
passwordcontroller.dispose();
}

@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
SystemNavigator.pop();
return true;
},
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.indigo,
title: Center(child: Text('Login Page')),
),
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Icon(
Icons.android,
size: 150,
),
),
Form(
key: _formkey,
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: TextFormField(
controller: emailcontroller,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
prefixIcon: Icon(Icons.alternate_email),
hintText: 'Email Address',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20))),
),
),
SizedBox(
height: 20,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: TextFormField(
controller: passwordcontroller,
obscureText: true,
keyboardType: TextInputType.visiblePassword,
decoration: InputDecoration(
prefixIcon: Icon(Icons.lock),
hintText: 'Password',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20))),
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: Align(
alignment: Alignment.centerRight,
child: TextButton(
onPressed: () {
Get.to(() => ForgetPasswordScreen());
},
child: Text("Forget Password?"))),
),
],
)),
RoundButton(
title: 'Login',
onTap: () {
if (_formkey.currentState!.validate()) {
setState(() {
loading = true;
});
_auth
.signInWithEmailAndPassword(
email: emailcontroller.text.toString(),
password: passwordcontroller.text.toString())
.then((value) {
Utils().toastMessage(value.user!.email.toString());
Get.to(() => HomeScreen());
setState(() {
loading = false;
});
}).onError((error, stackTrace) {
debugPrint(error.toString());
Utils().toastMessage(error.toString());//toast message display called from Utils.dart

setState(() {
loading = false;
});
});
}
},
loading: loading),
SizedBox(
height: 20,
),
Text("Don't have an Account?"),
TextButton(
onPressed: () {
Get.to(() => SignUpScreen());
},
child: Text('Sign Up'))
],
),
),
),
);
}
}

Create SignUpScreen() with Firebase Database With Getx to navigate from one page to another.

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:get/get.dart';
import 'package:login/pages/button.dart';
import 'package:login/pages/home.dart';
import 'package:login/pages/login.dart';
import 'package:login/pages/utils.dart';

import 'forget.dart';

class SignUpScreen extends StatefulWidget {
const SignUpScreen({super.key});

@override
State<SignUpScreen> createState() => _SignUpScreenState();
}

class _SignUpScreenState extends State<SignUpScreen> {
bool loading = false;
@override
void dispose() {
// TODO: implement dispose
super.dispose();
emailcontroller.dispose();
passwordcontroller.dispose();
}

final emailcontroller = TextEditingController();
final passwordcontroller = TextEditingController();

final _formkey = GlobalKey<FormState>();

FirebaseAuth _auth = FirebaseAuth.instance;

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: true,
backgroundColor: Colors.indigo,
title: Center(child: Text('Sign Up Page')),
),
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Icon(
Icons.android,
size: 150,
),
),
Form(
key: _formkey,
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: TextFormField(
controller: emailcontroller,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
prefixIcon: Icon(Icons.alternate_email),
hintText: 'Email Address',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20))),
validator: (value) {
if (value!.isEmpty) {
return 'Enter Email';
} // validator
},
),
),
SizedBox(
height: 20,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: TextFormField(
controller: passwordcontroller,
obscureText: true,
keyboardType: TextInputType.visiblePassword,
decoration: InputDecoration(
prefixIcon: Icon(Icons.lock),
hintText: 'Password',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20))),
validator: (value) {
if (value!.isEmpty) {
return 'Enter Password';
} // validator
},
),
),
],
)),
SizedBox(
height: 30,
),
RoundButton(
title: 'Sign Up',
onTap: () {
if (_formkey.currentState!.validate()) {
setState(() {
loading = true;
});
_auth
.createUserWithEmailAndPassword(
email: emailcontroller.text.toString(),
password: passwordcontroller.text.toString())
.then((value) {
setState(() {
loading = false;
});
}).onError((error, stackTrace) {
Utils().toastMessage(error.toString()); //called from the utils.dart

setState(() {
loading = false;
});
});
}
},
loading: loading),
const SizedBox(
height: 20,
),
const Text("Already have an Account?"),
TextButton(
onPressed: () {
Get.to(() => LoginScreen());
},
child: Text('Login'))
],
),
),
);
}
}

Now Lets create ForgetScreen() With Getx and Firebase

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:login/pages/login.dart';

import 'signup.dart';

class ForgetPasswordScreen extends StatelessWidget {
const ForgetPasswordScreen({super.key});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.indigo,
title: Center(child: Text('Forget Password Page')),
),
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Icon(
Icons.android,
size: 150,
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: TextFormField(
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
prefixIcon: Icon(Icons.alternate_email),
hintText: 'Email Address',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20))),
),
),
SizedBox(
height: 20,
),
MaterialButton(
color: Colors.indigo,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
height: 50,
minWidth: 150,
onPressed: () {},
child: Text(
'Login',
style: TextStyle(color: Colors.white),
),
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: () {
Get.to(() => SignUpScreen());
},
child: Text('Sign Up')),
TextButton(
onPressed: () {
Get.to(() => LoginScreen());
},
child: Text('Login')),
],
)
],
),
),
);
}
}

ForgetScreen.dart

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:login/pages/login.dart';
import 'package:login/pages/utils.dart';

import 'signup.dart';

class ForgetPasswordScreen extends StatefulWidget {
const ForgetPasswordScreen({super.key});

@override
State<ForgetPasswordScreen> createState() => _ForgetPasswordScreenState();
}

class _ForgetPasswordScreenState extends State<ForgetPasswordScreen> {
FirebaseAuth _auth = FirebaseAuth.instance;
final emailcontroller = TextEditingController();

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.indigo,
title: Center(child: Text('Forget Password Page')),
),
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Icon(
Icons.android,
size: 150,
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: TextFormField(
controller: emailcontroller,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
prefixIcon: Icon(Icons.alternate_email),
hintText: 'Email Address',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20))),
),
),
SizedBox(
height: 20,
),
MaterialButton(
color: Colors.indigo,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
height: 50,
minWidth: 150,
onPressed: () {
_auth
.sendPasswordResetEmail(email: emailcontroller.toString())
.then((value) {
Utils().toastMessage(
"We have sent an email link to recover password");
}).onError((error, stackTrace) {
Utils().toastMessage(error.toString());
});
},
child: Text(
'Send Email',
style: TextStyle(color: Colors.white),
),
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: () {
Get.to(() => SignUpScreen());
},
child: Text('Sign Up')),
TextButton(
onPressed: () {
Get.to(() => LoginScreen());
},
child: Text('Login')),
],
)
],
),
),
);
}
}

--

--