Flutter Google Sign In | Firebase Auth Login

Created At: 2022-06-16 17:53:16 Updated At: 2022-12-16 00:50:30

We will learn how to use Firebase for Google sing in or login in F,lutter. If you want to learn Flutter Facebook Login click here.

If you want to learn about Firebase login without Google click here

We will use google_sign_in plugin along with firebase_core and firebase_auth. So go ahead and install the plugins

  firebase_core:
  firebase_auth:
  google_sign_in:

First create a project in vscode or android studio. You would need to use package name (from android) and bundle id (from iOS) for Firebase  project set up. 

Android setup

Once you created the Firebase project, we need to do some settings for iOS android.

1. Google-services.json

We need to put the google-service.json file in the app/ folder

2. Internet set up

Make sure for android in /android/app/src/main/AndroidManifest.xml file you have internet connection set up

<uses-permission android:name="android.permission.INTERNET" />

android internet connection for firebase

It should look like this.

iOS setup

Put the below info in the plist.info

<key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeRole</key>
            <string>Editor</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <!-- TODO Replace this value: -->
                <!-- Copied from GoogleService-Info.plist key REVERSED_CLIENT_ID -->
                <string>com.googleusercontent.apps.826440745262-jc2e51jn4sfu7648uh66ina8ec6161ut</string>
            </array>
        </dict>
 </array>

And now it should look like below

flutter ios set up for google signin

Inside the <string> </string> we would put a value. Later down the down road. You can also find it in the info.plist file.

Project code

Now inside the lib folder create a file name auth_service.dart. Then iniside this create a class name AuthService. And it look like this

class AuthService{



}

Inside this class, we will put three methods

1. handleAuthState()

2. signInWithGoogle()

3. signOut()

Let's see the first method 

  //Determine if the user is authenticated.
  handleAuthState() {
    return StreamBuilder(
        stream: FirebaseAuth.instance.authStateChanges(),
        builder: (BuildContext context, snapshot) {
          if (snapshot.hasData) {
            return HomePage();
          } else {
            return const LoginPage();
          }
        });
  }

This method will use streamBuilder() to get Firebase instance from the Firebase server and help the app stay connected with Firebase. 

Based on that, we go to HomePage() or LoginPage()

Next method is signInWithGoogle(). Put the code below inside the AuthService class.

  signInWithGoogle() async {
    // Trigger the authentication flow
    final GoogleSignInAccount? googleUser = await GoogleSignIn(
        scopes: <String>["email"]).signIn();

    // Obtain the auth details from the request
    final GoogleSignInAuthentication googleAuth = await googleUser!.authentication;

    // Create a new credential
    final credential = GoogleAuthProvider.credential(
      accessToken: googleAuth.accessToken,
      idToken: googleAuth.idToken,
    );

    // Once signed in, return the UserCredential
    return await FirebaseAuth.instance.signInWithCredential(credential);
  }

The above method get's data from user device and then send the data to the Google server for authentiacation.  If the authentication is verified then, it returns token and user ID from the Google server.

At last we send the data to the Firebase server for login.

The last method is sign out method

 //Sign out
  signOut() {
    FirebaseAuth.instance.signOut();
  }

The above three methods are the core of the Google sign in and Firebase authentication.

Firebase Login page code

Let's create another file name loginin_page.dart and put the code below

class LoginPage extends StatefulWidget {
  const LoginPage({Key? key}) : super(key: key);

  @override
  _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  @override
  Widget build(BuildContext context) {
    final Size size = MediaQuery.of(context).size;

    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: const Text("Google Login"),
        backgroundColor: Colors.green,
      ),
      body: Container(
        width: size.width,
        height: size.height,
        padding: EdgeInsets.only(
            left: 20, right: 20, top: size.height * 0.2, bottom: size.height * 0.5),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            const Text("Hello, \nGoogle sign in",
                style: TextStyle(
                    fontSize: 30
                )),
            GestureDetector(
                onTap: () {
                  AuthService().signInWithGoogle();
                },
                child: const Image(width: 100, image: AssetImage('assets/google.png'))),
          ],
        ),
      ),
    );
  }
}

You see that, from here we call AuthService().signInWithGoogle(). Rest of the code is simple UI.

HomePage code

Let's create another dart file name home_page.dart and put the code below 

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  //String? user = FirebaseAuth.instance.currentUser!.email ?? FirebaseAuth.instance.currentUser!.displayName;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        color: Colors.white,
        width: MediaQuery.of(context).size.width,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[

            Text(
              FirebaseAuth.instance.currentUser!.displayName!,
              style: const TextStyle(
                  fontSize: 30, fontWeight: FontWeight.bold, color: Colors.black87),
            ),
            const SizedBox(
              height: 10,
            ),
            Text(
              FirebaseAuth.instance.currentUser!.email!,
              style: const TextStyle(
                  fontSize: 20, fontWeight: FontWeight.bold, color: Colors.black87),
            ),
            const SizedBox(
              height: 30,
            ),
            MaterialButton(
              padding: const EdgeInsets.all(10),
              color: Colors.green,
              shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)),
              child: const Text(
                'LOG OUT',
                style: TextStyle(color: Colors.white, fontSize: 15),
              ),
              onPressed: () {
                AuthService().signOut();
              },
            ),
          ],
        ),
      ),
    );
  }
}

Firebase Main

And now remove every thing from the main.dart file and put the code below

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      themeMode: ThemeMode.system,
      debugShowCheckedModeBanner: false,
      home: AuthService().handleAuthState(),
    );
  }
}

Sign out Problem

If you have signed out and log in the account you will see that, it does not ask for user account option. In that case you have do the follow.  Declare the below linke globally in AuthService file.

 final GoogleSignInAccount? googleUser = await GoogleSignIn(
        scopes: <String>["email"]);

And then inside signInWithGoogle() add

await googleUser.signIn();

And the signOut method

signOut() { 
    await googleUser.signOut();
    await FirebaseAuth.instance.signOut();
  }

Comment

Add Reviews