Flutter+Firebaseで色々なアカウント連携認証を実装

## はじめに
以下の記事で、Flutter+Firebaseでメールアドレス認証によるユーザ登録ができるアプリを作成した。

https://qiita.com/ninoko1995/items/722ae744c853e087f267

上記記事で作ったアプリのgithubレポジトリ:

https://github.com/ninoko1995/FlutterFirebaseDemo/tree/master

今回はこのアプリに、**~~メールリンク認証~~・google連携認証・Twitter連携認証**のそれぞれの認証方法を追加していく。
ちなみに今回の実装は、上のレポジトリの[`add_other_authentications`ブランチ](https://github.com/ninoko1995/FlutterFirebaseDemo/tree/add_other_authentications)に置いてある。

## メールリンク認証(調べた記事をまとめただけ。未実装。)
まずはメールリンク認証について調べる。
これまではメールアドレスとパスワードの入力でアカウント登録ができた。
ただこのままでは、その**メールアドレスと実際の所有者の紐付け**や、**メールアドレスの存在**は確認できていない。
入力されたメールアドレスにメールを送信し、リンクがクリックされた場合にアカウントを発行するように修正するため、色々調べてみる。

### Firebaseの設定

メール/パスワードプロバイダの構成を編集し、メールリンクを有効にする。
<img width=700 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/e73a7395-316e-05ce-2ed1-265d0de928a4.jpeg">

その後、追加の構成手順をそれぞれ実行する。

iOSの追加の構成手順

https://firebase.google.com/docs/auth/ios/email-link-auth?authuser=0

Androidの追加の構成手順

https://firebase.google.com/docs/auth/android/email-link-auth?authuser=0

ただ、なかなかflutterで書く記事が少なく、以下の記事を見た感じコピペでぽんっといける感じではなさそうだった。
今回はちょっとスキップさせてもらいます。

https://qiita.com/chooyan_eng/items/d7f47c81eac6e6206522

## google連携認証
以下の記事に沿って諸々設定する。

https://blog.dalt.me/2272


### Firebase側でのGoogle Sign inの設定
SHA1フィンガープリントを取得する部分で詰まったので、以下を参考に解決。
一度もAndroidのシミュレータを起動したことがなかったのが原因っぽい。

https://oc-technote.com/android/android%20%E3%82%AD%E3%83%BC%E3%82%B9%E3%83%88%E3%82%A2%E3%83%BB%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AF%E5%AD%98%E5%9C%A8%E3%81%97%E3%81%BE%E3%81%9B%E3%82%93/

これでエラーは無くなったが、次にパスワードの入力を求められた。
パスワードなどflutterの開発を始めてから設定した記憶がない。
が、調べていくと以下の記事を見つけた！！！！

https://qiita.com/taka0125/items/c408df4061a0af49c9b3

実は`degub.keystore`用のデフォルトパスワードは`android`だったらしい!!!
解決解決！

```
$ keytool -v -list -keystore ~/.android/debug.keystore
キーストアのパスワードを入力してください:
キーストアのタイプ: PKCS12
キーストア・プロバイダ: SUN

キーストアには1エントリが含まれます

別名: debug_keystore
作成日: 2021/10/15
エントリ・タイプ: PrivateKeyEntry
証明書チェーンの長さ: 1
証明書[1]:
所有者: CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
発行者: CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
シリアル番号: *****
有効期間の開始日: Fri Oct 15 18:42:33 JST 2021終了日: Tue Mar 02 18:42:33 JST 2049
証明書のフィンガプリント:
	 SHA1: ****
	 SHA256: ****
署名アルゴリズム名: SHA256withRSA
サブジェクト公開鍵アルゴリズム: 2048ビットRSA鍵
バージョン: 3

拡張:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
******
]
]



*******************************************
*******************************************
```

### Flutter側でGoogle Sign inの設定

インストールする`google_sign_in`のバージョンに注意。
最新(2021/10/14時点)のバージョン`5.1.1`を入れようとすると以下のようにエラーが発生したので、`5.0.0`にして解決。

```
$ flutter pub get
The current Dart SDK version is 2.13.4.                                 
                                                                        
Because photoapp depends on google_sign_in >=5.1.1 which requires SDK version >=2.14.0 <3.0.0, version solving failed.
Running "flutter pub get" in photoapp...                                
pub get failed (1; Because photoapp depends on google_sign_in >=5.1.1 which requires SDK version >=2.14.0 <3.0.0, version solving failed.)
```

#### コードの記述

##### 呼び出す部分
少し修正を加えたりもしたが、ほぼ記事のコピペ。

```dart:dart
Future<void> _onSignInGoogle() async {
    try{
      final googleLogin = GoogleSignIn(scopes: [
        'email',
        'https://www.googleapis.com/auth/contacts.readonly',
      ]);


      GoogleSignInAccount? signinAccount = await googleLogin.signIn();
      if (signinAccount == null) return;

      GoogleSignInAuthentication auth = await signinAccount.authentication;
      final credential = GoogleAuthProvider.credential(
        idToken: auth.idToken,
        accessToken: auth.accessToken,
      );
      FirebaseAuth.instance.signInWithCredential(credential);

      Navigator.of(context).pushReplacement(
          MaterialPageRoute(
            builder: (_) => PhotoListScreen(),
          )
      );
    } catch(e) {
      await showDialog(
          context: context,
          builder: (context) {
            return AlertDialog(
              title: Text('エラー'),
              content: Text(e.toString()),
            );
          }
      );
    }
  }

```

##### ボタン部分
ボタン部分の実装には、`flutter_signin_button`を用いた。
簡単に連携系のsigninボタンが作れるらしい。

https://pub.dev/packages/flutter_signin_button

```dart:dart
import 'package:flutter_signin_button/flutter_signin_button.dart';

//....

SignInButton(
  Buttons.Google,
  onPressed: () {
    _onSignInGoogle();
  },
),
```

#### 実際の挙動
以下のようにボタンタップすることで、よく見るgoogle連携認証画面が表示された！

<img width=250 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/852f454a-f75b-2333-bfbf-814761a211db.png"><img width=250 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/e53df39e-8852-c407-8e02-9d3c1fc2bcfe.png"><img width=250 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/98e392e8-3864-f594-6176-e24b0da10601.jpeg">

登録が完了すると、きちんとデータも格納されていた！！
![スクリーンショット_2021_10_15_19_57.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/8509c076-1050-638f-7f59-236116af768b.jpeg)
最強に簡単すぎる。



## twitter連携認証
### パッケージの選定
記事を調べると、色々なパッケージが存在していた。
それぞれの最終更新日(2021/10/14時点)を調べてみて、`twitter_login`を用いることに決定。
公式のページに使い方やコードサンプルが丁寧に書いてあるので、その通りにやればいける！！！

**flutter_twitter_login 1.1.0**
最終更新日　2018/5/24

https://pub.dev/packages/flutter_twitter_login

**flutter_twitter 1.1.3**
最終更新日　2019/5/21

https://pub.dev/packages/flutter_twitter

**twitter_login 4.0.1**
最終更新日　2021/1/15

https://pub.dev/packages/twitter_login

### UIの作成

ボタンは先程の`flutter_signin_button`を用いた。楽ちん便利！

### 実際の挙動
一度ログインしてしまったので3枚目の画像がちょっと違うが、TwitterでSNS連携するときの見慣れた画面であることはお分かりいただけるであろう！

<img width=250 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/06a405f0-f638-3e13-49fa-e863adfb5f38.png"><img width=250 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/0ef0f1d0-640f-d0b0-23c1-9742ac34df25.png"><img width=250 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/7a9b541e-8957-96da-1dd8-c858642b72b3.jpeg">

そんで、きちんとFirebase側に登録もされている！！！
![スクリーンショット_2021-10-15_21_37_28.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/88dc181f-e7ea-b529-d88d-5293ae4b3855.jpeg)

## まとめ
とりあえずGoogle認証とTwitter認証を追加できれば今の所はいいかな。
今後も、少しずつできる機能を増やしていって、自分のアプリを作るための勉強をしていきます！

ちなみに今回の実装は以下に置いてあります。
ブランチは`add_other_authentications`です。
`master`は[前回の記事](https://qiita.com/ninoko1995/items/722ae744c853e087f267)のままの状態なので、もし覗く人がいたら気をつけてください。

https://github.com/ninoko1995/FlutterFirebaseDemo/tree/add_other_authentications