Flutter - Firebase Google Sign-in Auth + SplashScreen using updated API

sai7xp

Sumanth

Posted on May 29, 2020

Flutter - Firebase Google Sign-in Auth + SplashScreen using updated API

0.Introduction

Have you ever wanted to implement user authentication in your flutter Application? Well, you've come to the right place..!
Let's see how to add GoogleSignIn() auth using Firebase Authenticationn.

What you'll learn

  • Adding SplashScreen to your app
  • Navigating user from the SplashScreen to AuthScreen or HomeScreen
  • GoogleSignIn Authentication

Demo of the final implementation...
Flow Chart

What is Firebase? (quick intro..)

Firebase is Google's mobile platform with a variety of services to build & ship our apps quickly. It is categorized as a NoSQL database and stores data in JSON like documents.

I writ code

1.Setup Firebase Project

Head over to Firebase Console then add a new project.
To keep things simple and short I'm not explaining every step here. Trust me next steps are pretty clear to add your app to firebase.

  • Make sure to set up a sign-in method in the Authentication section of firebase console. Otherwise, things are not gonna work as expected.

At a particular step, it asks you to enter SHA-1 Key to complete the process. Run this command in your cmd to get the SHA-1 key.

keytool -list -v -alias androiddebugkey -keystore C:\Users\YOUR_USER_NAME_HERE\.android\debug.keystore
Enter fullscreen mode Exit fullscreen mode

2.Write some Code

Before writing code let's understand what we are going to build.

When the user opens app for the first time we should navigate user from SplashScreen to AuthScreen.
Next time when the user opens the app we should check if user is already logged in or not.
If user = loggedIn then navigate to HomeScreen by skipping AuthScreen. ELSE navigate user from SplashScreen to AuthScreen.

Flow Chart

Let's write some code🥳

I write code

Packages that we'll use:

  • firebase_auth: ^0.18.3
    • firebase_core: ^0.5.2
    • google_sign_in: ^4.5.6

Add the above 3 packages to your pubspec.yaml file
And for every flutter app using Firebase, we must use the firebase_core package. And then you must initialize the app.
await Firebase.initializeApp();
If you don't initialize the app you may get the below error.

[core/no-app] No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp()

  1. Fire-up your preferred code editor and open your main.dart file. Remove all the boiler-plate code in main.dart file and add the below code.
import 'package:YOUR_PROJECT_NAME/screens/splashscreen.dart';
import 'package:YOUR_PROJECT_NAME/screens/authscreen.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';

// Defining routes for navigation
var routes = <String, WidgetBuilder>{
  "/auth": (BuildContext context) => AuthScreen(),
};

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MaterialApp(
    debugShowCheckedModeBanner: false,
    title: 'FaceBase',
    routes: routes,
    home: SplashScreen(),
  ));
}

Enter fullscreen mode Exit fullscreen mode

2.Let's build UI for the remaining screens

  • SplashScreen UI and Logic

Create a new dart file named splashscreen.dart inside the lib/screens folder.
Your splashscreen.dart should look like this..

import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_gsignin/screens/homescreen.dart';
import 'package:flutter/material.dart';

class SplashScreen extends StatefulWidget {
  _SplashScreenState createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen> {
  final FirebaseAuth _auth = FirebaseAuth.instance;
  User _user;
  @override
  void initState() {
    super.initState();
    initializeUser();
    navigateUser();
  }

  Future initializeUser() async {
    await Firebase.initializeApp();
    final User firebaseUser = await FirebaseAuth.instance.currentUser;
    await firebaseUser.reload();
    _user = await _auth.currentUser;
    // get User authentication status here
  }

  navigateUser() async {
    // checking whether user already loggedIn or not
    if (_auth.currentUser != null) {
      // &&  FirebaseAuth.instance.currentUser.reload() != null
      Timer(
        Duration(seconds: 3),
        () => Navigator.of(context).pushAndRemoveUntil(
            MaterialPageRoute(
                builder: (context) =>
                    HomeScreen(username: _auth.currentUser.displayName)),
            (Route<dynamic> route) => false),
      );
    } else {
      Timer(Duration(seconds: 4),
          () => Navigator.pushReplacementNamed(context, "/auth"));
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: Text("Design Your splash screen"),
        ),
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Create a another dart file named homescreen.dart inside the lib/screens folder.
And paste the below code into your homescreen

import 'package:firebase_gsignin/screens/authscreen.dart';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';

class HomeScreen extends StatefulWidget {
 final String username;
  HomeScreen({Key key, @required this.username}) : super(key: key);
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Hello "+ widget.username),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.exit_to_app),
            onPressed: () async {
              await FirebaseAuth.instance.signOut();
              await googleSignIn.disconnect();
              await googleSignIn.signOut();
              Navigator.of(context).pushAndRemoveUntil(
                  MaterialPageRoute(builder: (context) => AuthScreen()),
                  (Route<dynamic> route) => false);
            },
          ),
        ],
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            RaisedButton(
              onPressed: () async {
                await FirebaseAuth.instance.signOut();
                await googleSignIn.disconnect();
                await googleSignIn.signOut();
                Navigator.of(context).pushAndRemoveUntil(
                    MaterialPageRoute(builder: (context) => AuthScreen()),
                    (Route<dynamic> route) => false);
              },
              child: Text("Log Out"),
              color: Colors.redAccent,
            ),
            SizedBox(
              height: 10.0,
            ),
          ],
        ),
      ),
    );
  }
}

Enter fullscreen mode Exit fullscreen mode

Let's implement Firebase Authentication

Create a new file named authscreen.dart inside lib/screens folder in which we'll set up google sign in and AuthScreen UI.

  • Code for the authscreen.dart UI and logic:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_gsignin/screens/homescreen.dart';
import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';

String name;
String email;
String imageUrl;
final FirebaseAuth auth = FirebaseAuth.instance;
final GoogleSignIn googleSignIn = GoogleSignIn();
class AuthScreen extends StatefulWidget {
  @override
  _AuthScreenState createState() => _AuthScreenState();
}
class _AuthScreenState extends State<AuthScreen> {
  bool isVisible = false;
  Future<User> _signIn() async {
    await Firebase.initializeApp();
    final GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn();
    final GoogleSignInAuthentication googleSignInAuthentication =
        await googleSignInAccount.authentication;
    final AuthCredential credential = GoogleAuthProvider.credential(
      idToken: googleSignInAuthentication.idToken,
      accessToken: googleSignInAuthentication.accessToken,
    );
    // final AuthResult authResult = await auth.signInWithCredential(credential);
    // final User user = authResult.user;

    User user = (await auth.signInWithCredential(credential)).user;
    if (user != null) {
      name = user.displayName;
      email = user.email;
      imageUrl = user.photoURL;
    }
    return user;
  }
  @override
  Widget build(BuildContext context) {
    var swidth = MediaQuery.of(context).size.width;
    return Scaffold(
      body: Stack(
        children: <Widget>[
          Container(
            decoration: BoxDecoration(
                image: DecorationImage(
                    image: AssetImage("assets/images/bg.png"),
                    fit: BoxFit.cover)),
          ),
          Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Visibility(
                child: CircularProgressIndicator(
                  valueColor: AlwaysStoppedAnimation<Color>(Color(0xFFB2F2D52)),
                ),
                visible: isVisible,
              )
            ],
          ),
          Container(
            margin: const EdgeInsets.only(
              bottom: 60.0,
            ),
            child: Align(
              alignment: Alignment.bottomCenter,
              child: SizedBox(
                height: 54.0,
                width: swidth / 1.45,
                child: RaisedButton(
                  onPressed: () {
                    setState(() {
                      this.isVisible = true;
                    });
                    _signIn().whenComplete(() {
                      Navigator.of(context).pushAndRemoveUntil(
                          MaterialPageRoute(
                              builder: (context) => HomeScreen(username: name)),
                          (Route<dynamic> route) => false);
                    }).catchError((onError) {
                      Navigator.pushReplacementNamed(context, "/auth");
                    });
                  },
                  child: Text(
                    ' Continue With Google',
                    style: TextStyle(fontSize: 16),
                  ),
                  shape: RoundedRectangleBorder(
                    borderRadius: new BorderRadius.circular(30.0),
                  ),
                  elevation: 5,
                  color: Color(0XFFF7C88C),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

Enter fullscreen mode Exit fullscreen mode

3.Conclusion

Well, we've successfully implemented authentication in our flutter app.
congrats gif
If you've any doubts, you can find the GitHub repo of this super simple project in the following link:

GitHub logo Sai7xp / DEV.to-FirebaseAuth-Flutter

Flutter + Firebase Google SignIn Demo

App ScreenShots

screenshots

keep Fluttering!

Thank you for reading, if you found the article useful make sure to show some love.
-Moving Melody
Let's catch up on Twitter!

💖 💪 🙅 🚩
sai7xp
Sumanth

Posted on May 29, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related