FlutterとFirebase Authenticationを使ってGoogleアカウントでログインする

# FlutterとFirebaseAuthenticationを使ってGoogleアカウントでログインする
## 環境
MacOS Mojave 10.14.6
Flutter 1.10.11

## Firebase Authenticationの設定
* Firebase Consoleでプロジェクトを追加
* AndroidアプリのアプリケーションIDをAndroidパッケージ名に入力する。(/android/app/src/main/AndroidManifest.xmlのpackageに記載されている)
* Googleアカウントでログインできるようにする
FirebaseのAuthenticationのログイン方法をクリックしてGoogle認証を使えるようにする
![記事用1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221257/cf382a96-a412-707c-8473-c736fb477352.png)



* SHA-1フィンガープリントを設定するために以下のコマンドを叩いてSHA-1フィンガープリントを表示する

```
keytool -alias androiddebugkey -keystore ~/.android/debug.keystore -list -v
```

* Firebase ConsoleのAndroidアプリの設定に移動して、SHA-1フィンガープリントを設定する
![記事用2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221257/01718f29-a7c1-963f-422a-e78072ff41cf.png)


## アプリでの設定
* Firebase Authenticationから設定ファイル(google-services.json)をダウンロードする
* 設定ファイルをandroid/app配下に配置
* android/build.gradleに以下を追加

```
buildscript {
  dependencies {
      ・・・
      classpath 'com.google.gms:google-services:3.2.1'  // Google Services plugin
  }
}
```

* android/app/build.gradleに以下を追加

```
defaultConfig {
  ・・・
  multiDexEnabled true // ライブラリのメソッドが多すぎるとビルドエラーが発生するため
}

apply plugin: 'com.google.gms.google-services'
```

* pubspec.yamlにプラグインを追加する

```
dependencies:
  flutter:
    sdk: flutter
  # cloud_firestoreを使うなら0.4.0以上でないといけないと言われる
  firebase_core: ^0.4.0
  cloud_firestore: ^0.12.9+4
  firebase_auth: ^0.14.0+5
  google_sign_in: ^3.0.4
```

* firebase_authとgoogle_sign_inをimportする

```
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
```

* ボタンを押すとGoogleアカウントでサインインして、画面にユーザー名を表示する処理。

```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,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  FirebaseUser _user; // 現在ログインしているユーザー
  final _googleSignIn = new GoogleSignIn();
  final _auth = FirebaseAuth.instance;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Container(
        child: _user == null ? _googleSignInButton() : _signinWidget()
      )
    );
  }

  // Googleアカウントでサインインするボタン
  _googleSignInButton() {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Center(
          child: RaisedButton(
            child: Text("Google Sign In"),
            onPressed: () {
              // ログイン処理後、_userにsetStateで値を設定するとbuildが再度実行されて、
              // 画面にユーザー名が表示される。
              _handleGoogleSignIn().then((user) {
                setState(() {
                  _user = user;
                });
              }).catchError((error) {
                print(error);
              });
            },
          )
        ),
      ],
    );
  }

  // Googleアカウントでログインする処理
  Future<FirebaseUser> _handleGoogleSignIn() async {
    GoogleSignInAccount googleUser = await _googleSignIn.signIn();
    GoogleSignInAuthentication googleAuth = await googleUser.authentication;

    final AuthCredential credential = GoogleAuthProvider.getCredential(
      accessToken: googleAuth.accessToken,
      idToken: googleAuth.idToken,
    );

    FirebaseUser user = (await _auth.signInWithCredential(credential)).user;
    print("signed in " + user.displayName);
    return user;
  }

  // サインイン後に表示されるウィジェット
  _signinWidget() {
    return Column(
      children: <Widget>[
        Container(
          child: Text('Hi, ${_user.displayName}!'),
          padding: EdgeInsets.only(left: 10.0, top: 10.0),
        )
      ],
    );
  }
}
```

## まとめ
* わずか数行でGoogleアカウントでログインする処理が書ける。