In this post, I will be walking you through how to authenticate your flutter app with firebase. we won't be building anything fancy. just a demo app with three screens (Sign-Up, Sign-In and Homepage). This post assumes you've already setup your IDE with Flutter, we won't do that here, if you ready, Lets dive right in.
TLDR
If you already familiar with Flutter and Firebase and this post is too long for you to read, you can download the final project we would be building here on github
If you are not fully familiar with Flutter and Firebase, I would highly recommend you read through or better still code along so as to fully understand how things work.
Firstly let create our Flutter App.
if you are using VSCode, Open the Command Palette ( Ctrl + Shift + P) for windows and ( Cmd + Shift + P) for mac. click on New Project and feel free give the project any name you want. (Note: all letters has to be lower case). If you are using Android Studio as your IDE. click on file, then navigate to new flutter project. select flutter application then name the project and choose any folder path you want your project to be saved in. set package name is your app domain name, if you don't have that feel free to add this (com.example.yourappname) P.S: Write this down, we would be need it when we are ready to initialize our app with firebase, also Don't forget to tick all boxes then click finish.
Lets start creating our screens.
(Note: I would be using VSCode
for this article, if you're using Android Studio you can click the play button to run your app.)
open your terminal then navigate to your newly created flutter project then run your app with flutter run
. open lib/main.dart
file and delete MyHomePage
class, we would be creating ours shortly. Create a new folder, I will name mine screens. Now click on new file and name the file SignUp.dart
, do same for SignIn.dart
and Homepage.dart
respectively.
Open our newly created SignUp.dart file import material Design with import 'package:flutter/material.dart'
then create your signup class (Stateless Widget), you can do that by just typing stl
an auto create would popup, just click it (there you go π). Name it signup class, lets make the class return a text widget with "Sign Up" text temporarily, while we create our routes. Your SignUp class should look like this.
import 'package:flutter/material.dart';
class SignUpScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: Text('Sign Up'),
);
}
}
feel free to do the same for SignIn and Homepage files.
Open the main.dart file, you would notice the myHomePage class we deleted is already prompting us of an error, delete the entire line. we would be creating ours shortly. Now add this initialRoute: SignUp.id
.
Note: we could use any of this Material App properties (home
or initialRoute
) as our base route, but I prefer using initial route so as to make the naming convention the same, its doesn't really matter in our case, you could use either of the two.
PS: home
takes a widget as its property, while initialRoute
takes a string. Notice that its prompt an error, that is because we have not added the route to our SignUp class. Open SignUp and add this line static String id = 'sign-up';
, Do the same for both SignInScreen and HomepageScreen.
We've added our initial route, Our app would navigate to signup screen upon launch. Now lets create our routes
, this takes Map as argument. now add this lines SignUpScreen.id: (context) => SignUpScreen(),
Do same for both SignIn and Homepage route.
Your code should now look like this.
import 'package:flutter/material.dart';
import 'package:flutter_practice/Screens/Homepage.dart';
import 'package:flutter_practice/Screens/SignIn.dart';
import 'package:flutter_practice/Screens/SignUp.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
// home: SignUpScreen(),
initialRoute: SignUpScreen.id,
routes: {
SignUpScreen.id: (context) => SignUpScreen(),
SignInScreen.id: (context) => SignInScreen(),
HomepageScreen.id: (context) => HomepageScreen(),
},
);
}
}
Now hot restart you your app with capslock R
. You should see a black screen with a huge 'Sign Up' red text, (π Our screen is ugly, lets style it up a little). Im not going to walk through the styling process just copy and paste the below code, if you are following along.
import 'package:flutter/material.dart';
class SignUpScreen extends StatelessWidget {
static String id = 'sign-up';
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.lightBlueAccent,
body: Container(
child: Center(
child: Padding(
padding: const EdgeInsets.all(50.0),
child:
Column(mainAxisAlignment: MainAxisAlignment.center, children: [
Text(
'Sign Up Here',
style: TextStyle(fontSize: 30, color: Colors.white),
),
SizedBox(
height: 20,
),
TextFormField(
obscureText: true,
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
labelText: 'Email',
icon: Icon(
Icons.mail,
color: Colors.white,
),
errorStyle: TextStyle(color: Colors.white),
labelStyle: TextStyle(color: Colors.white),
hintStyle: TextStyle(color: Colors.white),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
errorBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
),
),
TextFormField(
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
labelText: 'Password',
icon: Icon(
Icons.lock,
color: Colors.white,
),
errorStyle: TextStyle(color: Colors.white),
labelStyle: TextStyle(color: Colors.white),
hintStyle: TextStyle(color: Colors.white),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
errorBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
),
),
RaisedButton(
onPressed: () {},
child: Text(
'Submit',
style: TextStyle(fontSize: 18),
),
)
]),
),
),
),
);
}
}
You can replicate that for the Signin screen as well, but if you like, feel free to style it to your own taste. We now have our auth screens styled up, we can now initialize our app with Firebase. Our SignUp Screen should look like this
Initializing App to Firebase
visit the firbase console here.
P.S: You need to have a google account, SignUp if you don't have one.
click on Add Project, enter the project name, then create new project, this should take less than 20seconds.( We would be building for Android on this post). incase you forgot your package name, open android/app/build.gradle scroll downwards you would see applicationId
thats you package name, Now click continue and download your google.services.json
file.
P.S: Make sure to click the download button just once, so as to prevent duplicate files been downloaded, if you've download this particular file before, delete it from your downloads folder. Now move the google.services.json
file you just downloaded into android/app
root folder. make sure its the right folder, if not its might prevent our app from running.
Once you've done click on next then open android/build.gradle
and add this line under dependencies classpath 'com.google.gms:google-services:4.3.4'
and this google()
under all project repositories if its not already added. Now open android/app/build.gradle. and add this line apply plugin: 'com.google.gms.google-services'
under app plugin then this implementation 'com.google.firebase:firebase-analytics'
under dependencies. (π«phew!! we are almost there).
We need to install some Firebase packages into our app namely firebase_auth
and firebase_core
. open pubspect.yaml
file and add this lines firebase_auth: ^0.18.0+1
and firebase_core: ^0.5.0
, make sure its properly aligned (pubspect.yaml could be funny at times, lolx).Once you've done that, click on Get Packages
this should install these packages into our app.
Now open main.dart
file and add this lines.
WidgetsFlutterBinding.ensureInitialized();
and await Firebase.initializeApp();
.
Your main.dart
file should now look like this
void main() async{
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
P.S: don't forget to import package:firebase_core/firebase_core.dart;
Close and rerun your app on the terminal, ctrl c
and flutter run
. If your app runs successfully, Congratulations!!! you have successfully initialized your flutter app with firebase.
if you encounter build errors. click here for fix.
Now that we've successfully created our screens and initialized our app with flutter, its time we start writing our authentication logic.
Authenticating our App with Flutter.
Open the SignUp file, since we using TextFormField
we would have to wrap our entire column into a form
widget. click the column widget and also click the yellow lightbulb that shows at the left side, select wrap with widget, then rename widget to Form
.
Form has a property called key add this key: _formKey
. This creates a container for form fields and make us get the form values upon save. We would have to create an instance for GlobalKey, which is the _formKey we added. add this line below our static id String final _formKey = GlobalKey<FormState>();
. Now create create email, password variable. String _email;
String _password;
. We now have to add a call back inside our TextFormField
to bind our email and password variable inside our callback. Add this line inside our TextFormField
onSaved: (emailValue) {
_email = emailValue;
},
Do same for password TextFormField. Now lets test and see if our binding works correctly. Inside our RaisedButton
add this line.
onPressed: () {
_formKey.currentState.save();
print(_email);
print(_password);
},
Type in a dummy email and password inside the text field and click submit, you should see the text you typed inside your terminal. Lets move on.
Now add this line inside the onPressed callback
onPressed: () async {
_formKey.currentState.save();
try {
final new_user = await _auth.createUserWithEmailAndPassword(
email: _email, password: _password);
if (new_user != null) {
Navigator.pushNamed(context, HomepageScreen.id);
}
} catch (e) {
print(e);
}
},
The above code takes our _auth
instance from firebase and pass our email and password values into the createUserWithEmailAndPassword
function from firebase. its also check if user is not available, if so its navigate us to the homescreen page. if there is an error, its catches the error and print it on the terminal.
We have to enable email and password authentication from firebase console
Now visit the firebase console here then click on your project, on the left, click on authentication, click on sign in methods, You can see Email/Password is disabled. enable it and save.
Before we test, lets go to our Homepage screen and add some contents to it, so its doesn't show a complete blank screen. Inside the Homepage screen, delete the entire class and add this
class HomepageScreen extends StatelessWidget {
static String id = 'homepage';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: null,
actions: <Widget>[
IconButton(
icon: Icon(Icons.close),
onPressed: () {
}),
],
title: Text(
'Homepage',
style: TextStyle(color: Colors.white),
),
backgroundColor: Colors.lightBlueAccent,
),
body: Center(child: Text('Homepage'),),
);
}
}
Open terminal and run hot restart. Now test sign up, its should sign the user up and navigate to Homepage Screen. You can click on users on firebase console, to see the list of registered users.
P.S: When testing make sure your password is 6 characters or above, firebase won't accept anything lower than that.
Lets implement signOut
on our app.
Inside the method in our IconButton
widget, add this
_auth.signOut();
. also import firebase auth
Navigator.pop(context);import 'package:firebase_auth/firebase_auth.dart';
and create its instance like so final _auth = FirebaseAuth.instance;
. Your Homepage screen should now look like this.
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
class HomepageScreen extends StatelessWidget {
static String id = 'homepage';
final _auth = FirebaseAuth.instance;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: null,
actions: <Widget>[
IconButton(
icon: Icon(Icons.close),
onPressed: () {
// Implement logout functionality
_auth.signOut();
Navigator.pop(context);
}),
],
title: Text(
'Homepage',
style: TextStyle(color: Colors.white),
),
backgroundColor: Colors.lightBlueAccent,
),
body: Center(child: Text('Homepage')),
);
}
}
Now run hot reload r
and test the log out functionality. its should take you back to the SignUp Screen. We are almost there, lets implement the SignIn functionality
Underneath the RaisedButton
create a FlatButton and give it Text widget like so.
FlatButton(
onPressed: () {
Navigator.pushNamed(context, SignInScreen.id);
},
child: Text('Sign In'),
)
The navigator.pushNamed
line would make our app navigate to the Sign In Screen
. Now test and see if its working.
Open the SignIn Screen and wrap the column
widget with a form widget add the key property also. Create an email and password variable like we did when implementing the Sign Up functionality, I wont walk through that again, you can check the SignUp Screen or scroll up for reference.
Inside the onPressed callback in our RaisedButton
add this line
onPressed: () async{
_formKey.currentState.save();
try {
final user = await _auth.signInWithEmailAndPassword(
email: _email, password: _password);
if (user != null) {
Navigator.pushNamed(context, HomepageScreen.id);
}
} catch (e) {
print(e);
}
},
This should navigate you into HomepageScreen, if you entered your correct credentials. (phew π! Finally, haha). We have successfully authentication our app with firebase auth. Congratulations!!!.
Feel free to correct me if you spot any errors, you can also checkout my future posts where I would be walking you through how to add forget password, reset password with firebase.
Your feedbacks and comments would be greatly appreciated. Thanks for your time.
Top comments (0)