Flutter Firebase Google Sign In Example

Flutter Firebase Google Sign In Example

In this tutorial, We will learn how to use flutter firebase google sign in. Most popular among the mobile developer’s community is firebase. We will build a splash screen, a login screen and a home screen to navigate user after login or if they already signed in.

Google Sign In method on firebase is from firebase trusted provider for authentication.Every app requires sign in method to login users.Firebase provider seamless authentication.

Step 1:

Create a firebase project and punch in the package name,app name and the SHA1 Key. This step is straightforward. While creating a project you will get be asked to download google_service.json file for android. Save it for later use.

Step 2:

Open up project from console list and navigate to projects and click on authentication.Goto methods tab and enable Google Sign In method from the list.

Step 3:

Now paste google_service.json file into android/app directory.

Step 4:

Now that firebase project is setup,Lets do some code.Paste in following dependencies on packages.json file and run pub get command.

dependencies:
  flutter:
    sdk: flutter
  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.2
  firebase_auth: ^1.2.0
  firebase_core: ^1.1.0
  provider: ^5.0.0
  google_sign_in: ^4.5.1

firebase_auth and google_sign_in is for firebase authentication with google sign in.

provider is for state management

Step 5:

Create splash_view.dart file from the lib directory and paste in the below code.

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'auth_service.dart';
import 'home_view.dart';
class SplashView extends StatefulWidget {
  AuthService _authService;
  SplashView({@required AuthService authService}):_authService = authService;
  @override
  _SplashViewState createState() => _SplashViewState();
}
class _SplashViewState extends State<SplashView> {
  @override
  void initState() {
    super.initState();
    _runTimer();
  }
  void _runTimer() async{
    Future.delayed(Duration(seconds: 2), () {
      _checkLogin();
    });
  }
  void _checkLogin() async{
    var user = await widget._authService.getFirebaseCurrentUser();
    if(user != null){
      Navigator.<em>of</em>(context).pushReplacement(MaterialPageRoute(builder: (_) => HomeView()));
    }
  }
  @override
  Widget build(BuildContext context) {
    return _buildSplash();
  }
}
Widget _buildSplash(){
  return Container(
    color: Colors.<em>grey</em>[50],
    child: _buildCenter(),
  );
}
Widget _buildCenter(){
  return  Center(
    child: Column(
      mainAxisSize: MainAxisSize.max,
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Container(
            margin: EdgeInsets.all(16.0),
            child: Icon(Icons.<em>account_box</em>)),
        Container(
            margin: EdgeInsets.all(16.0),
            child: CircularProgressIndicator())
        //buildCircularProgress(model)
      ],
    ),
  );
}

The above widget stateful widget and on initstate method we set up a Future for 2 sec as Splash Time. Once the splash time completed we are checking up Firebase authentication. If the user credential is null then that user has not signed in yet so he will be navigated to sign_in_view.dart using MaterialPageRoute else we will navigate the user to home_view.dart.

Step 6:

Now that we are done with building splash_view,Lets build sign_in_view.Create a file named sign_in_view.dart and paste in the following.

import 'package:flutter/material.dart';
import 'package:google_sign_in_example/auth_service.dart';
class SignInView extends StatefulWidget {
  @override
  _SignInViewState createState() => _SignInViewState();
}
class _SignInViewState extends State<SignInView> {
  var authService = AuthService();
  void onPressGoogleSignIn() async{
    var userCredentials = await authService.signInWithGoogle();
    if(userCredentials == null){
       ScaffoldMessenger.<em>of</em>(context).showSnackBar(SnackBar(content: Text('Failed to sign in')));
    }else{
       Navigator.<em>of</em>(context).pushReplacement(MaterialPageRoute(builder: (_) => SignInView()));
    }
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home'),),
      body: Center(
        child: ElevatedButton(
          pressed:()=> onPressGoogleSignIn(),
          child: Text('Google Sign In'),
        ),
      ),
    );
  }
}

In the above code,On press of google sign in button using google_sign_in packages method to sign in with google and this line awaits for user credentials while popping up sign in with Google Dialog.We are using AuthService class here and this class learnt further in this tutorial.

Step 7:

Create a file named home_view.dart to navigate signed user here.Paste in the following code.

import 'package:flutter/material.dart';
class HomeView extends StatefulWidget {
  @override
  _HomeViewState createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home'),),
      body: Center(
        child: Text("Home View",style: TextStyle(fontSize: 22),),
      ),
    );
  }
}
Step 8:

Now lets discuss important part thats AuthService class.Paste in the following.

import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
class AuthService{
  final  _firebaseAuth = FirebaseAuth.<em>instance</em>;
  Future<User> getFirebaseCurrentUser() async{
   return  _firebaseAuth.currentUser;
  }
  Future<UserCredential> signInWithGoogle() async {
    final GoogleSignInAccount googleUser = await GoogleSignIn().signIn();
    final GoogleSignInAuthentication googleAuth = await googleUser.authentication;
    final credential = GoogleAuthProvider.<em>credential</em>(
      accessToken: googleAuth.accessToken,
      idToken: googleAuth.idToken,
    );
    return await FirebaseAuth.<em>instance</em>.signInWithCredential(credential);
  }
  Future<bool> signOut() async{
    await _firebaseAuth.signOut();
    var user = await getFirebaseCurrentUser();
    if(user != null){
      return false;
    }else{
      return true;
    }
  }
}

In the above code we have signInWithGoogle where in we are creating object of GoogleSignIn() and calling a method signIn() this will pop up Google Sign In dialog when user selects the email this returns user credentials once when we have user credentials we need to pass on this google user credentials with Firebase Authentication so that Firebase will create a account for this particular email.

Full Code :
import 'package:flutter/material.dart';
import 'package:flutter_anonymous_app/auth_service.dart';
import 'package:flutter_anonymous_app/splash_view.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 Anonymous Login',
      theme: ThemeData(
        primarySwatch: Colors.<em>blue</em>,
      ),
      home: SplashView(authService: AuthService(),),
    );
  }
}
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'auth_service.dart';
import 'home_view.dart';
class SplashView extends StatefulWidget {
  AuthService _authService;
  SplashView({@required AuthService authService}):_authService = authService;
  @override
  _SplashViewState createState() => _SplashViewState();
}
class _SplashViewState extends State<SplashView> {
  @override
  void initState() {
    super.initState();
    _runTimer();
  }
  void _runTimer() async{
    Future.delayed(Duration(seconds: 2), () {
      _checkLogin();
    });
  }
  void _checkLogin() async{
    var user = await widget._authService.getFirebaseCurrentUser();
    if(user == null){
      //user has no previous anonymous signup credentials so sign in anonymously.
      var userCred = await widget._authService.signInAnonymously();
      checkUserCreds(userCred);
    }else{
      //user is already logged so navigate to home screen.
      Navigator.<em>of</em>(context).pushReplacement(MaterialPageRoute(builder: (_) => HomeView()));
    }
  }
  void checkUserCreds(UserCredential userCredential){
    if(userCredential == null){
      Navigator.<em>of</em>(context).pushReplacement(MaterialPageRoute(builder: (_) => HomeView()));
    }
  }
  @override
  Widget build(BuildContext context) {
    return _buildSplash();
  }
}
Widget _buildSplash(){
  return Container(
    color: Colors.<em>grey</em>[50],
    child: _buildCenter(),
  );
}
Widget _buildCenter(){
  return  Center(
    child: Column(
      mainAxisSize: MainAxisSize.max,
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Container(
            margin: EdgeInsets.all(16.0),
            child: Icon(Icons.<em>account_box</em>)),
        Container(
            margin: EdgeInsets.all(16.0),
            child: CircularProgressIndicator())
        //buildCircularProgress(model)
      ],
    ),
  );
}
import 'package:flutter/material.dart';
class HomeView extends StatefulWidget {
  @override
  _HomeViewState createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home'),),
      body: Center(
        child: Text("Home View",style: TextStyle(fontSize: 22),),
      ),
    );
  }
}
import 'package:firebase_auth/firebase_auth.dart';
class AuthService{
  final  _firebaseAuth = FirebaseAuth.<em>instance</em>;
  Future<User> getFirebaseCurrentUser() async{
   return  _firebaseAuth.currentUser;
  }
  Future<UserCredential> signInAnonymously() async {
    return _firebaseAuth.signInAnonymously();
  }
  Future<bool> signOut() async{
    await _firebaseAuth.signOut();
    var user = await getFirebaseCurrentUser();
    if(user != null){
      return false;
    }else{
      return true;
    }
  }
}
<!-- wp:code -->
<pre class="wp-block-code"><code></code></pre>
<!-- /wp:code -->