A month of Flutter: Sign in with Google

Abraham Williams - Dec 18 '18 - - Dev Community

Originally published on bendyworks.com.

Building on the work configuring Firebase Auth for Android and iOS, it's time to go get a user's details. This will be leveraging the already installed google_sign_in and firebase_auth packages.

The big change is the addition of the Auth class.

class Auth {
  Auth({
    @required this.googleSignIn,
    @required this.firebaseAuth,
  });

  final GoogleSignIn googleSignIn;
  final FirebaseAuth firebaseAuth;

  Future<FirebaseUser> signInWithGoogle() async {
    final GoogleSignInAccount googleAccount = await googleSignIn.signIn();
    // TODO(abraham): Handle null googleAccount
    final GoogleSignInAuthentication googleAuth =
        await googleAccount.authentication;
    return firebaseAuth.signInWithGoogle(
      accessToken: googleAuth.accessToken,
      idToken: googleAuth.idToken,
    );
  }
}
~~~{% endraw %}

This class gets passed a {% raw %}`FirebaseAuth`{% endraw %} instance and a {% raw %}`GoogleSignIn`{% endraw %} instance for interactions with the external authentication services. On {% raw %}`GoogleSignIn`{% endraw %} the [{% raw %}`signIn`{% endraw %} method](https://pub.dartlang.org/documentation/google_sign_in/latest/google_sign_in/GoogleSignIn/signIn.html) will trigger a user account selection prompt. When the user confirms their account selection a [{% raw %}`GoogleSignInAccount` instance](https://pub.dartlang.org/documentation/google_sign_in/latest/google_sign_in/GoogleSignInAccount-class.html) will be returned. On `GoogleSignInAccount` I'll call [`authentication`](https://pub.dartlang.org/documentation/google_sign_in/latest/google_sign_in/GoogleSignInAccount/authentication.html) to get the [current user's tokens](https://pub.dartlang.org/documentation/google_sign_in/latest/google_sign_in/GoogleSignInAuthentication-class.html). Finally I'll exchange the `GoogleSignInAuthentication` for a `FirebaseUser` with [`signInWithGoogle`](https://pub.dartlang.org/documentation/firebase_auth/latest/firebase_auth/FirebaseAuth/signInWithGoogle.html).

I added a TODO to [improve error handling](https://github.com/abraham/birb/issues/48) so it doesn't get forgotten.

The app now has an authenticated [{% raw %}`FirebaseUser`{% endraw %}](https://pub.dartlang.org/documentation/firebase_auth/latest/firebase_auth/FirebaseUser-class.html) with all the accompanying details.

I'll now update `SignInFab` to leverage the new `Auth` service and print out the user's {% raw %}`displayName`{% endraw %} in the Flutter logs.{% raw %}

~~~dart
void _handleSignIn() {
  auth
      .signInWithGoogle()
      .then((FirebaseUser user) => print('Hi ${user.displayName}'));
}
~~~{% endraw %}{% raw %}

~~~log
I/flutter (29142): Hi Birb Dev
~~~{% endraw %}

{% raw %}`SignInFab`{% endraw %} will also need to be passed an {% raw %}`Auth`{% endraw %} instance in {% raw %}`_MyHomePageState`{% endraw %}.{% raw %}

~~~dart
SignInFab(
  auth: Auth(
    firebaseAuth: FirebaseAuth.instance,
    googleSignIn: GoogleSignIn(),
  ),
)
~~~{% endraw %}

This is what the account selector looks like on Android:

![Sign in flow on Android](https://thepracticaldev.s3.amazonaws.com/i/tmcslg9phm3h73p5ckmd.png)

iOS prompts to allow access to google.com:

![Sign in flow on iOS](https://thepracticaldev.s3.amazonaws.com/i/mb3rgfgnb8slw67c1umc.png)

Most of the new code is actually tests and mocking the external Google and Firebase APIs. It's complected and deserves it's own article so come back tomorrow to learn more.

## Code changes

- [#44 Add sign in service](https://github.com/abraham/birb/pull/44)
Enter fullscreen mode Exit fullscreen mode
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .