[flutter]FirebaseAuthenticationでgoogleアカウントを使ってサインインする方法


# 実装した経緯
Flutterを勉強していると、ほとんどの場合、FirebaseAuthを使ったユーザー名とパスワード認証に遭遇します。パスワードを忘れた際には、毎回メールで確認したり、「パスワードを忘れた？」という手順を踏む必要があり、手間がかかります。

そこでユーザーのサインインとログインをgoogleまたはappleアカウントで実装しました

![スクリーンショット 2024-01-30 9.02.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3686950/3f1db96e-3de2-be24-711d-1b695f76174d.png)


今回はgoogleアカウントでサインインの実装について書きます


:::note warn
警告
この記事では、firebaseの初期設定は完了している前提で進めます！
:::

### メリット
#### 利便性向上: 
ユーザーが既にAppleアカウントまたはGoogleアカウントを持っている場合、新たにユーザー名とパスワードを設定する手間が省かれ、サインインが簡単になります。

#### セキュリティ向上: 
AppleとGoogleはセキュリティに力を入れており、サインインプロセスもセキュアです。ユーザーのデータを保護するために、信頼性が高い認証システムを利用できます。

#### ソーシャルログイン:
ソーシャルログインを実装することで、ユーザーエンゲージメントを向上させ、ユーザーアカウントの作成を促進できます。



### デメリット
#### プラットフォーム依存性: 
AppleとGoogleアカウントのみをサポートする場合、特定のプラットフォームに依存することになり、他の認証方法を希望するユーザーに制限を課すことになるかもしれません。

#### ユーザーの選択肢の制限:
ユーザーに提供できる認証方法が制限されるため、一部のユーザーには不便かもしれません。例えば、FacebookやTwitterなどの他のソーシャルプラットフォームを利用したいユーザーもいるかもしれません。


***

## 1.Authentication設定
自分のプロジェクトのfirebaseページ
↓
Authenticationを選択
↓
ログイン方法を設定をタップ！
![スクリーンショット 2024-01-30 6.47.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3686950/8ac7386d-ab43-0b9a-8b23-a0adb8216cfb.png)
↓
Firebaseダッシュボードの左メニューから→ログイン方法を設定をタップ→google選択
![スクリーンショット 2024-01-30 6.58.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3686950/b75af00c-0f57-03ab-2f1f-a232c58cb1c7.png)
↓
Firebaseプロジェクト設定 -> 一般でサポートメールも追加してください。
ここで、Google（プロバイダーの下）を有効にし、プロジェクト名とサポートメールを入力し、保存をクリックします。
![スクリーンショット 2024-01-30 6.53.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3686950/89bf4ff3-014d-c19e-002e-d3ce5c5a3f55.png)

## 2.Info.plistに追加
Android端末は準備完了！
iOS端末で使用するには、もう1つだけ必要なことがあります。
まずプロジェクトディレクトリ -> `ios` -> `Runner` ->`GoogleService-Info.plist`

```GoogleService-Info.plist
<key>REVERSED_CLIENT_ID</key>
	<string>ここの値をコピーして</string> 
```


プロジェクトディレクトリ -> ios -> Runner -> 
`Info.plist`ファイルを開き、そこに以下を追加してください：

```Info.plist
	<key>CFBundleURLTypes</key>
	<array>
		<dict>
			<key>CFBundleTypeRole</key>
			<string>Editor</string>
			<key>CFBundleURLSchemes</key>
			<array>
				<string>ここに貼り付け</string>
			</array>
		</dict>
	</array>
```


以上のステップで準備完了です
次は実際にコード書いていきます！

## 3.firebaseの初期化

```dart:main.dart
Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  runApp(
      child: MyApp(),
  );
}
```

## 4.googleサインインの実装

全体像
ui層でgoogleボタン押される
↓
`signInWithGoogle`
↓
`authenticateWithGoogle`
↓
成功したらtrue
失敗はfalse


## signInWithGoogle
`signInWithGoogle`はui層でボタンが押されたら最初に呼ばれる

```dart:auth_view_model.dart
Future<bool> signInWithGoogles(WidgetRef ) async {
    try {
    //googleサインイン処理
      UserCredential? user = await authenticateWithGoogle();
      if (user != null) {
      //サインイン成功
        return true;
      }  
      //失敗
      return false;
    } catch (e) {
      //エラーハンドリング
      return false;
    }
  }
```

:::note info
UserCredentialとは
・Authenticationで使用されるクラスで、ユーザーの認証情報を表しています。

・Authenticationを利用する際、ユーザーがログインやサインアップを行うと、このUserCredentialオブジェクトが生成され、アプリケーション内でユーザーの認証状態を管理するのに使用されます。
:::

## authenticateWithGoogle
  Googleでのサインインプロセスを実行するメソッドです。
  Googleアカウントを使用してユーザー認証を行い、その結果をFirebase Authで使用するためのAuthCredentialに変換します。
   戻り値はFirebase Authを通じて認証されたUserCredentialです。
  

```dart:auth_view_model.dart
   Future<UserCredential?> authenticateWithGoogle() async {
    FirebaseAuth auth = FirebaseAuth.instance;

    // Googleアカウントでのログインを試みます。
    final GoogleSignIn googleSignIn = GoogleSignIn();

    // GoogleSignInAccountオブジェクトを取得します。
    // ユーザーがGoogleアカウントでログインした場合にこのオブジェクトが返されます。
    final GoogleSignInAccount? googleSignInAccount =
        await googleSignIn.signIn();

    // ユーザーがGoogleアカウントでのログインに成功した場合
    if (googleSignInAccount != null) {
      final GoogleSignInAuthentication googleSignInAuthentication =
          await googleSignInAccount.authentication;

      // Googleアカウントの認証情報からAuthCredentialを生成します。
      final AuthCredential credential = GoogleAuthProvider.credential(
        accessToken: googleSignInAuthentication.accessToken,
        idToken: googleSignInAuthentication.idToken,
      );

      // 生成されたAuthCredentialを使用してFirebaseでのサインインを行います。
      final UserCredential userCredential =
          await auth.signInWithCredential(credential);
      return userCredential;
    }
    return null;
  }
```

## 5.UI層

UI層ではview_modelのsignInWithGoogleから
trueが返ってきたら画面遷移すると完璧です！



```dart:login_and_signup.dart
 Future<void> onGoogleSignIn() async {
    try {
      final result = await AuthViewModel().signInWithGoogle();
      if (result) {
       //googleサインイン完了
       //画面遷移などのコード
      } 
    } catch (e) {
     //エラー処理
    }
  }
```
## まとめ
最後まで読んでいただきありがとうございます！
私はまだまだflutter勉強中ですので、間違っている箇所などがありましたらコメントください
また質問も気軽にして下さい
次はappleサインインのやり方！でお会いしましょう！！