初心者がKotlinとFirebase Authenticationでログイン機能をつくってみた

#Firebase Authenticationとは

https://firebase.google.com/products/auth/?authuser=0
アプリを作るにあたって、ログイン機能が必要な場合に１から構築するのはとっても大変そう。
Firebase Authenticationのサービスを利用すればお手軽に構築できちゃうんだから使わない手はないよね。


#準備
こちらの手順でローカルで作ってるアプリとFirebaseを接続しよう。
https://qiita.com/Natsuki_on_Rails/items/38cfcf6829e282b6f63e

#ログイン機能を作る

##ログイン方法を決める
Firebaseのコンソールでログイン方法を決めよう
<img width="249" alt="スクリーンショット 2018-12-30 16.29.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/6eed46b7-5e33-d5ee-c79e-50ebf16a7fd0.png">
<img width="1039" alt="スクリーンショット 2018-12-30 16.29.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/beacc44c-a3f8-da28-bea3-4ddb7336162c.png">

Authentication -> ログイン方法にてやりたいログインの仕方を有効にする
今回はとりあえずメール/パスワード方式でのログインをやってみるよ。
<img width="984" alt="スクリーンショット 2018-12-30 16.30.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/a0ee662a-5b1a-04ab-b5e8-1aa16669f8f4.png">

##依存関係をアプリレベルの build.gradle ファイルに追加
```
implementation 'com.google.firebase:firebase-auth:XX.X.X'
```
↑を
<img width="339" alt="スクリーンショット 2018-12-30 16.35.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/f3b64afb-ad12-44c3-cf0e-3e9ed2038cc8.png">
アプリレベルのbuild.gradleの
<img width="637" alt="スクリーンショット 2018-12-30 16.36.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/144c2890-6163-f73f-b140-7d273823b5a5.png">
ここに追加！
バージョンはfirebase-coreのやつに合わせた方がいい感じ
（firebase-coreは準備のとこで追加したやつだよ）

これでAuthenticationのもろもろが使えるようになった。

##実装する
Firebaseのドキュメントに結構丁寧に書いてあるんだけどひととおり
https://firebase.google.com/docs/auth/android/password-auth?authuser=0

イメージとしてはこんな感じのログイン画面をつくりたい
<img width="287" alt="スクリーンショット 2018-12-30 16.42.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/367a9e2f-50fb-ecd0-86d9-5709eaacb79f.png">

###レイアウトファイルの実装

```activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <Button
            android:text="@string/signup"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/SignUpButton" android:layout_marginTop="13dp"
            app:layout_constraintTop_toBottomOf="@+id/guideline" app:layout_constraintStart_toStartOf="parent"
            android:layout_marginStart="73dp"/>
    <Button
            android:text="@string/login"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/LoginButton" android:layout_marginTop="13dp"
            app:layout_constraintTop_toBottomOf="@+id/guideline" app:layout_constraintEnd_toEndOf="parent"
            android:layout_marginEnd="73dp"/>
    <TextView
            android:text="@string/e_mail"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/emailLabel" app:layout_constraintTop_toTopOf="parent"
            android:layout_marginTop="88dp" app:layout_constraintEnd_toStartOf="@+id/emailEditText"
            android:layout_marginEnd="14dp" app:layout_constraintStart_toStartOf="parent"
            android:layout_marginStart="40dp" android:labelFor="@+id/emailEditText"/>
    <TextView
            android:text="@string/password"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/passLabel" android:layout_marginTop="32dp"
            app:layout_constraintTop_toBottomOf="@+id/emailLabel" app:layout_constraintStart_toStartOf="parent"
            android:layout_marginStart="40dp" android:labelFor="@+id/passEditText"/>
    <EditText
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:inputType="textEmailAddress"
            android:ems="10"
            android:id="@+id/emailEditText"
            app:layout_constraintBottom_toBottomOf="@+id/emailLabel"
            app:layout_constraintTop_toTopOf="@+id/emailLabel" app:layout_constraintEnd_toEndOf="parent"
            android:layout_marginEnd="58dp" android:autofillHints=""/>
    <EditText
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:inputType="textPassword"
            android:ems="10"
            android:id="@+id/passEditText"
            app:layout_constraintTop_toTopOf="@+id/passLabel" app:layout_constraintBottom_toBottomOf="@+id/passLabel"
            app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="58dp" android:autofillHints=""/>
    <android.support.constraint.Guideline android:layout_width="wrap_content" android:layout_height="wrap_content"
                                          android:id="@+id/guideline" app:layout_constraintGuide_begin="204dp"
                                          android:orientation="horizontal"/>
</android.support.constraint.ConstraintLayout>
```

適当です<(_ _)>

###Activityファイルの実装
```MainActivity.kt

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import com.google.firebase.auth.FirebaseAuth


class MainActivity : AppCompatActivity() {

    private lateinit var auth: FirebaseAuth

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        auth = FirebaseAuth.getInstance()

        val buttonSignUp = findViewById<Button>(R.id.SignUpButton)
        val buttonLogin = findViewById<Button>(R.id.LoginButton)



        buttonSignUp.setOnClickListener {

            val emailEditText = findViewById<EditText>(R.id.emailEditText)
            val emailText = emailEditText.text.toString()

            val passEditText = findViewById<EditText>(R.id.passEditText)
            val passText = passEditText.text.toString()


            auth.createUserWithEmailAndPassword(emailText, passText)
                .addOnCompleteListener(this) { task ->
                    if (task.isSuccessful) {
                        Toast.makeText(
                            baseContext, "SignUp 成功",
                            Toast.LENGTH_SHORT
                        ).show()
                    } else {
                        Toast.makeText(
                            baseContext, "SignUp 失敗",
                            Toast.LENGTH_SHORT
                        ).show()
                    }
                }
        }

        buttonLogin.setOnClickListener {

            val emailEditText = findViewById<EditText>(R.id.emailEditText)
            val emailText = emailEditText.text.toString()

            val passEditText = findViewById<EditText>(R.id.passEditText)
            val passText = passEditText.text.toString()

            auth.signInWithEmailAndPassword(emailText, passText)
                .addOnCompleteListener(this) { task ->
                    if (task.isSuccessful) {
                        Toast.makeText(
                            baseContext, "Login 成功",
                            Toast.LENGTH_SHORT
                        ).show()
                    } else {
                        Toast.makeText(
                            baseContext, "Login 失敗",
                            Toast.LENGTH_SHORT
                        ).show()
                    }

                }

        }
    }
}
```

とりあえずログインできることを確かめるだけのものです。

①FirebaseAuthをインポート

```kotlin
import com.google.firebase.auth.FirebaseAuth
```

②FirebaseAuthオブジェクトの共有インスタンスを取得

```kotlin
private lateinit var auth: FirebaseAuth
// ...
auth = FirebaseAuth.getInstance()
```

③SignUpボタン押下時の処理
入力したEmailやパスワードを元にユーザを登録してる。
登録に成功したかどうかはトーストで出してる（しょぼい）

```kotlin
            auth.createUserWithEmailAndPassword(emailText, passText)
                .addOnCompleteListener(this) { task ->
                    if (task.isSuccessful) {
                        Toast.makeText(
                            baseContext, "SignUp 成功",
                            Toast.LENGTH_SHORT
                        ).show()
                    } else {
                        Toast.makeText(
                            baseContext, "SignUp 失敗",
                            Toast.LENGTH_SHORT
                        ).show()
                    }
                }
```

④Loginボタン押下時の処理
こっちもおんなじ感じ。
ユーザが登録されてれば成功、いなければ失敗する。

```kotlin
            auth.signInWithEmailAndPassword(emailText, passText)
                .addOnCompleteListener(this) { task ->
                    if (task.isSuccessful) {
                        Toast.makeText(
                            baseContext, "Login 成功",
                            Toast.LENGTH_SHORT
                        ).show()
                    } else {
                        Toast.makeText(
                            baseContext, "Login 失敗",
                            Toast.LENGTH_SHORT
                        ).show()
                    }

                }
```

##動きをみてみよう
<img width="283" alt="スクリーンショット 2018-12-30 17.11.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/e467d432-97af-e1ad-8464-f8ce3af8c164.png">

SIGNUPボタンを押すと
<img width="123" alt="スクリーンショット 2018-12-30 17.11.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/3224bee8-d68b-9e82-fdcf-80ee43528743.png">

成功のトーストが出て
<img width="1064" alt="スクリーンショット 2018-12-30 17.11.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/11743ab3-15ab-ef15-482b-52dc1294eae6.png">

ユーザが登録されてる！

　LOGINボタンを押すと
<img width="111" alt="スクリーンショット 2018-12-30 17.11.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/f5455fc6-4f4e-6276-4336-17a5d6d39380.png">

いえーい
（ちょーしょぼい）

これで別な画面に遷移したりすればいい感じのアプリになるのではないでしょうか。