FlutterでFirebase ～パスワードでの認証編～

# はじめに
FlutterでFirebaseを使いたくなったのでメモ
[FluttreFire](https://firebase.flutter.dev/)というものがあるとのことでこちらを使う。

やりたいのは
- 認証
- 画像の保存
- ユーザーのデータの保存

今回は認証周りをやったのでメモしておく。

WebもAndroidも動いちゃったので素晴らしい。
iOSはまだ試していない^^;

# FlutterFireの準備
[FlutterFire Overview](https://firebase.flutter.dev/docs/overview)に書いてある通りに準備する。

1. flutter pub add firebase_core を実行
1. dart pub global activate flutterfire_cli を実行
1. flutterfire configure を実行
1. 必要なimportなどを記載する

# Flutter Authentication

基本的にはチュートリアルの[Get Started with Firebase Authentication on Flutter](https://firebase.flutter.dev/docs/auth/start)に書いてある通りにやっていくと、準備はできる

1. flutter pub add firebase_auth を実行
1. flutter run を実行
1. import 'package:firebase_auth/firebase_auth.dart'; をmain.dartに追加

ローカルシミュレータは今のところ使っていないので省略。
(使いたくなったら使う)

authStateChanges、idTokenChanges、userChangesの3つのメソッドが紹介されているが、この時点ではこんなのがあるんだねでいいと思う。
この辺、どういうときにどのメソッドを実装すべきなのか、現時点でよくわかっていない。
多分、Firebaseの認証関係の流れを理解しないとわからないんじゃないかと思うが、userChangesメソッドを使っていこうと思う。

次に[Manage Users in Firebase](https://firebase.flutter.dev/docs/auth/manage-users)を見て、そういうメソッドがあんだねーと知っておく。
ここのページは意外と重要だと思うので、ちゃんと読んでおくといい。
今回は、とりあえずユーザー登録からログイン、ログアウト、ユーザー削除までを試したいので、パスワード認証を試す。

[Authenticate with Firebase using Password-Based Accounts on Flutter](https://firebase.flutter.dev/docs/auth/password-auth)を見て、実際に処理を作る。


## Firebaseの初期化

初期化はこんな感じで作成。
_userId、_password、_emailはTextFieldに紐づく変数。

```dart 
  void _firebaseInit() async {
    // iIrebaseの初期化
    WidgetsFlutterBinding.ensureInitialized();
    await Firebase.initializeApp(
      options: DefaultFirebaseOptions.currentPlatform,
    );

    FirebaseAuth.instance
        .userChanges()
        .listen((User? user) {
      if (user == null) {
        // サインアウトしている
        print('userChanges : User is currently signed out!');
        setState(() {
          _userId = "";
          _password = "";
          _email = "";
        });

      } else {
        // サインインしている
        print('userChanges : User is signed in!');
        setState(() {
          _userId = user.uid;
        });
      }
    });
  }
```

## ユーザー登録
画面に入力されたメールアドレスとパスワードを使って登録を行う。

```dart
  void _register() async {
    try {
      final credential = await FirebaseAuth.instance.createUserWithEmailAndPassword(
        email: _email,
        password: _password,
      );
    } on FirebaseAuthException catch (e) {
      if (e.code == 'weak-password') {
        print('The password provided is too weak.');
      } else if (e.code == 'email-already-in-use') {
        print('The account already exists for that email.');
      }
    } catch (e) {
      print(e);
    }
  }
```


## ログイン

```dart
  void _login() async{
    try {
      final credential = await FirebaseAuth.instance.signInWithEmailAndPassword(
          email: _email,
          password: _password
      );
    } on FirebaseAuthException catch (e) {
      if (e.code == 'user-not-found') {
        print('No user found for that email.');
      } else if (e.code == 'wrong-password') {
        print('Wrong password provided for that user.');
      }
    }
  }
```

## ログアウト
```
  void _logout() async {
    await FirebaseAuth.instance.signOut();
  }
```

## ユーザー削除
```dart
  void _delete() async {
    final user = FirebaseAuth.instance.currentUser;
    await user?.delete();
  }
```

## パスワードリセット
パスワードを忘れたときのために。
setLanguageCode()メソッドで送信するメールのロケールを指定できる。
指定しないと英語で送られてくる。
この辺は、端末の言語設定から指定するようにしたほうがいいかもしれない。

```dart
  void _resetPassword() async {
    await FirebaseAuth.instance.setLanguageCode("ja");
    await FirebaseAuth.instance.sendPasswordResetEmail(email: _email);
  }
```