【Flutter】FirebaseのEmailログインの実装方法

# 環境
OS: macOS Catalina (10.15.4)
Flutter: Version 1.12.13+hotfix.8
Android Studio: Version 3.5.2

# 事前準備
・Flutterの環境構築が完了していること
　[Flutterの環境構築](https://qiita.com/mkosuke/items/7957e71968aefc6558be)
・Firebaseとアプリの連携は完了していること
　[FlutterアプリとFirebaseを連携する](https://firebase.google.com/docs/flutter/setup?hl=ja)
・Firebase Consoleで認証が有効になっていること
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514870/432a2104-9012-cc03-c11b-6bd7ccc3d966.png)

# 実装方法

## ①ライブラリのインストール

今回使用するライブラリは以下です。
・firebase_auth: ^0.15.5+3(最新のライブラリを使用しましょう。)

パッケージページリンク
[firebase_auth](https://pub.dev/packages/firebase_auth)


pubspec.yamlに以下を記述

```pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  # 省略
  firebase_auth: ^0.15.5+3  #追記
```

`flutter packages get`でインストール

## ②実装

今回は以下のような画面で実装しています。
パスワードなどの細かい部分も実装しているのでコピペで使えると思います。

### 画面

![Simulator Screen Shot - iPhone 11 Pro Max - 2020-05-01 at 20.29.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514870/1006f426-a117-b9e7-ddc9-bb09b3467a87.png)

### コード

```email_login_page.dart
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';

class EmailAuthPage extends StatefulWidget {
  @override
  _EmailAuthPageState createState() => _EmailAuthPageState();
}

class _EmailAuthPageState extends State<EmailAuthPage> {

  final emailTextController = TextEditingController();
  final passwordTextController = TextEditingController();
  bool _showPassword = true;
  final _fireBaseAuth = FirebaseAuth.instance;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('メールでログインする'),
        backgroundColor: Colors.redAccent,
      ),
      body: Container(
        padding: EdgeInsets.all(20),
        child: Column(
          children: <Widget>[
            Column(
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Text('Email',style: TextStyle(fontSize: 16,fontWeight: FontWeight.bold),),
                Padding(padding: EdgeInsets.only(top: 5),),
                TextField(
                  keyboardType: TextInputType.emailAddress,
                  decoration: InputDecoration(
                    prefixIcon: Icon(Icons.mail_outline),
                    hintText: 'Email',
                  ),
                  controller: emailTextController,
                ),
              ],
            ),
            Padding(padding: EdgeInsets.only(top: 20),),
            Column(
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Text('Password' ,style: TextStyle(fontSize: 16,fontWeight: FontWeight.bold),),
                Padding(padding: EdgeInsets.only(top: 5),),
                TextField(
                  decoration: InputDecoration(
                    prefixIcon: Icon(Icons.vpn_key),
                    suffixIcon: IconButton(
                      icon: _showPassword
                          ? Icon(Icons.remove_red_eye,color: Colors.green,)
                          : Icon(Icons.remove_circle_outline,color: Colors.red,),
                      onPressed: (){
                        setState(() {
                          _showPassword = !_showPassword;
                        });
                      },
                    ),
                    hintText: 'Password',
                  ),
                  obscureText: _showPassword,
                  keyboardType: TextInputType.visiblePassword,
                  controller: passwordTextController,
                ),
              ],
            ),
            Padding(padding: EdgeInsets.only(top: 50),),
            Container(
              width: double.infinity,
              child: RaisedButton(
                  child: Text(
                    "メールアドレスでログインする",
                    style: TextStyle(color: Colors.white),
                  ),
                  color: Colors.redAccent,
                  shape: StadiumBorder(),
                  onPressed: (){
                    _signInEmail(AuthType.signIn);
                  }
              ),
            ),
            Padding(padding: EdgeInsets.only(top: 50),),
            Container(
              width: double.infinity,
              child: RaisedButton(
                child: Text(
                  "メールアドレスで新規登録する",
                  style: TextStyle(color: Colors.white),
                ),
                color: Colors.black,
                shape: StadiumBorder(),
                onPressed: (){
                  _signInEmail(AuthType.signUp);
                },
              ),
            ),
          ],
        ),
      ),
    );
  }

  void _signInEmail(AuthType type) async {
    final email = emailTextController.text;
    final password = passwordTextController.text;
    AuthResult result;
    try {
      if (type == AuthType.signIn) {
        // 成功したらresultにユーザー情報が入る
        result = await _signIn(email, password);
      } else if (type == AuthType.signUp) {
        // 成功したらresultにユーザー情報が入る
        result = await _signUp(email, password);
      }
      // 成功したら画面遷移する
      Navigator.pushNamed(context, 'routeName');
    } catch (e) {
      print(e);
      return;
    }
  }

  Future<AuthResult> _signIn(String email, String password) async {
    return _fireBaseAuth.signInWithEmailAndPassword(email: email, password: password);
  }

  Future<AuthResult> _signUp(String email, String password) async {
    return _fireBaseAuth.createUserWithEmailAndPassword(email: email, password: password);
  }
}

enum AuthType {
  signIn,
  signUp,
}
```

# 実装のポイント

``` email_login_page.dart
// firebaseAuthのインスタンスを生成
final _fireBaseAuth = FirebaseAuth.instance;
```

``` email_login_page.dart

  // ログインのメソッドに入力したEmailとPasswordを渡す
  Future<AuthResult> _signIn(String email, String password) async {
    return _fireBaseAuth.signInWithEmailAndPassword(email: email, password: password);
  }

  // 新規登録のメソッドに入力したEmailとPasswordを渡す
  Future<AuthResult> _signUp(String email, String password) async {
    return _fireBaseAuth.createUserWithEmailAndPassword(email: email, password: password);
  }
```

# 最後に

Email、PasswordのログインはFirebaseのログインの中でも一番簡単なため
かなりオススメです！

電話番号の認証はこちらで実装しているので
参考にしてみてください！

[【Flutter】Firebaseの電話番号認証の実装](https://qiita.com/t0_inoue/items/0f990143ca8fbf1964b1)