やるぜ！Flutter！Firebaseで認証してみる（Google編)

前回FirestoreのCRUDを作ってみたけど、Firestoreはアプリ利用者がみんなアクセスするから、ユーザごとにアクセスできる場所を分けていかないといけない。誰でも何でも見れるようにはできないからね。
そうすると、どうしてもアプリにログインしてもらわないとならない。ログインしてもらう以上、認証の仕組みが必要だ。
てなわけで、認証書を作ってみるよ。
[前回作ったアプリ](https://qiita.com/apricotcomic/items/a657396d1c745e0a54c8)にログイン画面を追加して、入力されたID（メールアドレス）をFirestoreのcollectionのキーに使うよ。
図にするとこんな感じ。
![認証とFirestoreの関係.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/126d38b3-d546-c3f4-a71f-fc9a1c12f3f5.png)
よしできた。これで勝ったも同然。
ではこれを順番に実装していこう。

# 1.Firebaseを設定する
まずはFirebaseで認証機能を使えるように設定するよ。
[前回作ったアプリ](https://qiita.com/apricotcomic/items/a657396d1c745e0a54c8)に追加するので、前回Firebaseに登録したアプリのコンソールを表示するよ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/e6c0628c-eb77-6c8a-db57-d4e97d5a7396.png)
下にスクロールするとAuthenticationのでっかいボタンが表示されるから、これをクリックだ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/36cdb8b3-0564-3321-36d6-684b74c94be0.png)
そうすると、Authenticationの管理画面が表示されるよ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/329b1d74-7f68-ad20-4a2f-3554ed25eed0.png)
Authenticationの見出しの下にある「Sighn-In Method」タブをクリックすると、このプロジェクトで使えるログイン方式を指定できる画面が表示されるよ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/a92bdf5a-c9de-b1c1-e56c-918c91493f03.png)
今回はGoogleのメールアドレスでログインできるようにするので、追加のプロバイダの「Google」をクリックだ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/46632e50-6cae-f77e-e04e-26b4adf520a2.png)
そうすると、「SHA1フィンガープリントを設定しろ」と言われます。
フィンガープリントは本番用とデバッグ用それぞれ設定しないといけないが、今回はデバッグ用を設定するよ。
デバッグ用のフィンガープリントは次のコマンドで取得するよ。
```cmd
keytool -list -v -alias androiddebugkey -keystore 《debug.keystoreをフルパスで指定》
```
debug.keystoreはWindowsでは通常C:\Users\《ユーザ名》\.androidフォルダの中にあるよ。これをフルパスで指定してあげると、「キーストアのパスワードを入力してください」と言われる。
設定した覚えはないが「android」と入力すればいいらしいよ。
そうするとキーストアの内容が表示されるので、この中の「証明書のフィンガプリント」のSHA1の内容をFirebaseに設定しよう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/c2b38743-5c3b-eab7-ad03-6c95fac07c31.png)
Firebaseのプロジェクトの設定画面を開き、一番下までスクロールさせると、フィンガープリントを追加するリンクがあるよ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/140d2387-7e7f-bbe3-5418-e0ae65c127fa.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/6734118d-477e-a288-8230-f7908b823bec.png)
このリンクをクリックすると、証明書のフィンガープリントを入力するエリアが展開されるので、さっき表示した証明書のフィンガープリントをここにコピペすればOK。
最初の画面で「SHA1フィンガープリントを追加」と言われたからSHA1で説明書いてきたけど、SHA256も設定できるようだ。
今時だったらSHA256で設定しておいたほうがいいかもね。
ここまで設定したら、Authenticationの画面に戻って、Googleを有効にしよう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/1b2a0e0b-efbf-ffa3-07f4-3e1e01851271.png)
有効にすると、プロジェクトの公開名とプロジェクトのサポートメールを設定する画面が開くよ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/120be6f5-7280-88e7-122c-53ee7d71b662.png)
どうやらプロジェクトの設定でこれらの項目が設定されていないと表示されるみたいだ。
とりあえずテストなので、適当な値を入れて保存するよ。
そうしたら、こんな注意書きが表示された。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/edaa8939-688f-fb92-5b56-cc74e7ec7f30.png)
OK、心に留めておくよ。
完了を押すと、Googleが設定された状態になっているよ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/a34a26e1-b27c-97ff-20d8-d415e3464ebd.png)
今日はこの辺で勘弁してやるけど、もっといろいろ設定したかったら「新しいプロバイダを追加」をクリックして追加してくれ。
Firebaseの設定は、とりあえずここまでだ。

# 2.アプリにFirebase Authenticationを追加する
って、[公式](https://firebase.google.com/docs/auth/flutter/start?hl=ja&authuser=1)と同じタイトルになっちゃった。じゃあ公式読んどけって話になってしまうが、そこはそれ、俺流にやってやるぜ。
ちなみに[前回](https://qiita.com/apricotcomic/items/a657396d1c745e0a54c8)Firebase SDKはインストールしているので、インストール済みの体で進めていくよ。
## (1)プラグインをインストールする
プロジェクトのフォルダでfirebase_authを追加する。
```cmd
flutter pub add firebase_auth
```
そうすると、何かがダウンロードされてなんちゃらdependencies!とか言われて、いかにも何か終わったようになるよ。
公式にはこの後flutter runしろって言っているが、とりあえず放っておいて、先に進んじゃおう。
Googleで認証する場合は、google_sign_inも追加しないといけないらしい。
```cmd
flutter pub add google_sign_in
```
これもさっきと同じようになんちゃらdependencies!って言われたらOK。
## (2)SignInを実装する
さて、いよいよ実装だ。
やることは下記の通りだ。
・googleサインイン画面をつくる。
　サインインしたら今まで表示していた一覧画面を表示する。
・main.dartで最初に開く画面を一覧からgoogleサインイン画面に変更する。
### ①サインイン画面を作る
まずはサインインする画面を作るよ。
と言っても、実際にサインインする処理はgoogleの方でやってくれるから、私たちはその処理を呼び出すところを実装できればOKだ。

とりあえず実装する前に、認証関係の処理を格納するフォルダを作ったよ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/ce4ffd32-b937-2d8e-8699-a9a273be7a43.png)
新規作成するプログラムは「google_signin.dart」という名前にしたよ。
中身はこんな感じ。

```google_signin.dart
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:apricotcomicdemo/view/cat_list.dart';

class GoogleSignin extends StatelessWidget {
  const GoogleSignin({Key? key}) : super(key: key);

  // ↓ここから公式の処理を丸パクリ
  Future<UserCredential> signInWithGoogle() async {
    // Trigger the authentication flow
    final GoogleSignInAccount? googleUser = await GoogleSignIn().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);
  }
  // ↑ここまで公式の処理を丸パクリ

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Google Login')),
      body: Center(
        child: Column(children: <Widget>[
          ElevatedButton(
            onPressed: () async {
              // サインイン画面を表示する
              signInWithGoogle();
              // 猫一覧画面を表示する
              Navigator.push(
                  context, MaterialPageRoute(builder: (context) => const CatList()));
            },
            child: const Text('Google'),
          )
        ]),
      ),
    );
  }
}
```
認証する処理は、[公式](https://firebase.google.com/docs/auth/flutter/federated-auth?hl=ja&authuser=1)に書いてあったのを丸パクリしたよ。何一つ変えてない、まさに麿パクリだ。
それを、ボタンが押されたら呼び出して、その後今まで表示していた一覧画面を表示するようにしたよ。

### ②main.dartを変更する
立ち上がったら猫一覧を呼んでいた処理を、上で作った認証画面を呼び出すようにしたよ。
```main.dart
/* 変更前 */
routes: <String, WidgetBuilder>{
        '/': (_) => const CatList(),       //cat_list.dartを呼び出し
      },
     ↓   
/* 変更後 */
routes: <String, WidgetBuilder>{
        '/': (_) => const GoogleSignin(), //google_signin.dartを呼び出し
      },
```

これだけ。これだけだ。
# 3.動かしてみる
エミュレータ起動してからflutter runすると、こんな画面になったよ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/6e49fe2c-fb36-3cd5-d9e7-4d15a9f94b8c.png)
適当に作ったから、ボタン位置とか素人丸出しだね。
そんなことは気にしないで、「Google」ボタンを押してみよう。
そしたらこんな画面になったよ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/7b52d405-2ce8-53e8-06bb-53650272481a.png)
一回テストしたからもうログインしているIDも表示されているけど、ちゃんとGoogleにつながっているみたいだ。テストで登録したIDをクリックすると、一覧画面が表示されるよ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/a41c849c-5620-0933-716f-28b818676d9e.png)
ログオフ機能やログインしたユーザの情報を取ってきたり、ログイン済みならログイン画面を表示しないとか、やることはまだまだたくさんありそうだが、とりあえずつなぐことはできたよ。公式のコピペで動いちゃうなんて、なんてお手軽なんでしょう。

またそのうちなにかしたら記事にするよ。いらねーよ、とか言わないでね。
それではその時まで、チ・ヴェディアーモ！