【Nuxt.js,Firebase】ユーザー登録、ログイン実装②storeの保持/管理、正常に登録できた時/エラーが起きた時の処理

#はじめに
こんにちは！
今回は[前回の記事](https://qiita.com/Yudai_35_/items/cb6f360863cf2838b7d5)の続き、storeの保存、正常に登録できた時、エラーが起きた時の処理についてアウトプットしていきます！

#対象
・firebaseを使用してのユーザー登録、ログイン機能の実装を行いたい方
・[前回の記事](https://qiita.com/Yudai_35_/items/cb6f360863cf2838b7d5)までの内容がお済みの方

##使用環境

|使用技術  |バージョン  |
|:-:|:-:|
|nuxt.js  |2.15.7 |
|firebase |9.6.1  |
|firebase-tools |9.23.3  |
|@nuxtjs/tailwindcss |4.2.0  |

##使用ファイル,概要

|ファイル名  |概要  |
|:-:|:-:|
|pages/singup  |新規登録ページ |
|pages/login |ログインページ  |
|plugins/firerbase.js |firebase導入  |
|store/index.js |ログインデータの管理&保持  |

#Vuexストアの設定

Vuexストアを使いemail,password,loginの管理&保持を行う処理を記述していきます

```javascript:store/index.js
export const state = () => ({
    user: {
        email: "",
        password: "",
        login: false
    }
});

export const actions = {
    confirmLogin({ commit }) {
        this.$auth.onAuthStateChanged(function (user) {
            if (user) {
                commit("getData", { email: user.email, password: user.password });
                commit("yesLogin");
            } else {
                commit("noLogin");
            }
        });
    }
};

export const mutations = {
    getData(state, payload) {
        state.user.email = payload.email;
        state.user.password = payload.password;
    },
    yesLogin(state) {
        state.user.login = true;
    },
    noLogin(state) {
        state.user.login = false;
    },
    signOut(state) {
        state.user.email = "";
        state.user.password = "";
        state.user.login = false;
    }
};

```

・stateでemail,passwordの情報を保持、loginの状態を管理&保持している。
・actionsで、confirmLoginが呼ばれた時にログインの切り替え、新規の登録の処理を行う。
・mutationsで、ユーザの状態,情報内容によって処理が行われ、stateの情報が書き替わる。

#新規登録/登録時、エラー時の処理

```vuejs:pages/singup.vue
<template>
  <!-- 新規登録 -->
  <div
    class="text-center px-2 pb-4 my-24 max-w-xl m-auto bg-gray-200 font-serif"
  >
    <h2
      class="
        text-2xl
        my-10
        border-b-2 border-green-300
        w-10/12
        pt-6
        pb-3
        pl-3
        m-auto
        text-left
      "
    >
      Sing up
    </h2>
    <form @submit.prevent class="" novalidate>
      <!--👇入力中はエラーメッセージを非表示にしている--->
      <input
        type="”email”"
        name="”email”"
        required="required"
        placeholder="E-mail"
        v-model="user.email"
        @input="isInput"
        class="border-2 h-12 w-10/12 mb-5 autofocus"
      />
      <p class="text-red-400">{{ emailErrorMassage }}</p>
      <input
        type="”password”"
        name="”passWord”"
        required="required"
        placeholder="PassWord"
        v-model="user.password"
        @input="isInput"
        class="border-2 h-12 w-10/12 mb-5"
      />
      <p class="text-red-400">{{ passwordErrorMassage }}</p>
      <button @click="register" class="h-12 w-10/12 my-4 bg-green-300">
        登録
      </button>
      <button @click="googleLogin" class="h-12 w-10/12 my-4 bg-green-300">
        Googleで登録
      </button>
    </form>
    <div class="tracking-widest items-center my-4">
      <a href="/login" class="h-12 text-blue-500">登録済みの方</a>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      user: {
        email: "",
        password: "",
      },
      emailErrorMassage: "",
      passwordErrorMassage: "",
//👇正規表現は理解が難しいので、この形をコピペして使いましょう
      emailRegexp: /^[a-z\d][\w.-]*@[\w.-]+\.[a-z\d]+$/i,
      passwordRegexp: /^(?=.*?[a-z])(?=.*?\d)[a-z\d]{8,20}$/i,
    };
  },
    register() {
      //emailにemailRegexpの正規表現の形ではないメールアドレスが入力されたら45行目が発火する
      if (!this.emailRegexp.test(this.user.email)) {
        this.emailErrorMassage =
          "このメールアドレスは無効です。正しく入力してください";
      }
      //passwordにpasswordRegexpの正規表現の形だはないパスワードが入力されたら49行目が発火する
      if (!this.passwordRegexp.test(this.user.password)) {
        this.passwordErrorMassage =
          "このパスワードは無効です。半角英数字を含んで8-20文字の範囲内で入力してください。";
      }
      //emailの入力欄に何も入力されていなかったら53行目が発火する
      if (this.user.email === "") {
        this.emailErrorMassage = "メールアドレスを入力してください";
      }
      //passwordの入力欄に何も入力されていなかったら57行目が発火する
      if (this.user.password === "") {
        this.passwordErrorMassage = "パスワードを入力してください";
      }
      //emailErrorMassage または passwordErrorMassage に何か当てはまっている時処理を返す
      if (this.emailErrorMassage !== "" || this.passwordErrorMassage !== "") {
        return;
      }
      //正常に登録できた時の処理
      this.$auth
        .createUserWithEmailAndPassword(this.user.email, this.user.password)
        .then((user) => {
          alert("登録しました");
          this.$store.dispatch("confirmLogin");
          this.$router.push("/top");
        })
        //エラーが起きたときの処理
        .catch((error) => {
          console.log({ code: error.code, message: error.message });
          //👇 auth/invalid-emailの意味
          //Authに渡したメールアドレスが、メールアドレスの形をしていない場合に出るエラーです。 （例：email : aaaaa）
          if (error.code === "auth/invalid-email") {
            this.emailErrorMassage = "このメールアドレスは適切ではありません";
            //👇 auth/email-already-in-useの意味
            //メールアドレスが既に登録済みである場合に出るエラーです。
          } else if (error.code === "auth/email-already-in-use") {
            this.emailErrorMassage = "このメールアドレスは既に登録されています";
          } else {
            alert("エラーが発生いたしました。再度入力をお願いします。");
          }
        });
    },
    //👇入力中はエラーメッセージを非表示にしている
    isInput() {
      this.emailErrorMassage = "";
      this.passwordErrorMassage = "";
    },
  },
};
</script> 

```
**email,passwordが正常な入力がされていない時の処理(register)**
・未入力時、設定された正規表現の形に反している形の時、`.catch,emailErrorMassage or passwordErrorMassage`の処理内容に一致が小ざいた時に発生する処理が記述。

・正規表現に関しての参考記事は[こちら](https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_Expressions)
(コード内のコメントを参考)

**firebase使用時の必須時効**
・`this.$auth.createUserWithEmailAndPassword`はfirebaseを使用しての新規登録機能を実装するときに**使用するルール**が決められている。この型を丸ごと覚えてしまいましょう。

**正常に登録できた時の処理(.then)**
・登録完了をアラートで通知
・`store/index.js`の`confirmLogin`処理を呼び出し、stateにemail,passwordの情報を保持、login情報/状態をtureへ変更させる。
・登録に成功したら、強制的にTOPページへ移動させる

(コード内のコメントを参考)

**エラー発生時の処理(.catch)**
・メールアドレスの形に適していない時のエラー（auth/invalid-email）
・既に登録済みのメールアドレスを使用している時のエラー（auth/email-already-in-use）

エラーコードを書くときも`(error.code === "auth/email-already-in-use")`みたいな書き方が基本なので覚えておきましょう。

firebaseのエラーコード一覧は[こちら](https://firebase.google.com/docs/auth/admin/errors?hl=ja) 参考。

(コード内のコメントを参考)

また、email,password入力中はエラーメッセージを非表示にしています。（isInput部分）

#登録成功時

![スクリーンショット 2021-12-18 16.20.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2114750/e97f05e6-218c-fdc3-0eb0-2e641d346833.png)

#エラー発生時
・未入力時のエラー
![スクリーンショット 2021-12-25 21.50.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2114750/51131801-1293-27e3-bbdf-548cddc0bbfa.png)

・適した形で入力されていないときのエラー
![スクリーンショット 2021-12-25 21.52.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2114750/dda340af-67bb-93a4-8b59-8b705e22cab8.png)



#ログイン/登録時、エラー時の処理

```vuejs:pages/login.vue
<template>
  <!-- ログインページ -->
  <div
    class="text-center px-2 pb-4 my-24 max-w-xl m-auto bg-gray-200 font-serif"
  >
    <h2
      class="
        text-2xl
        my-10
        border-b-2 border-green-300
        w-10/12
        pt-6
        pb-3
        pl-3
        m-auto
        text-left
      "
    >
      Login
    </h2>
    <form @submit.prevent class="" novalidate>
      <input
        type="”email”"
        name="”email”"
        required="required"
        placeholder="E-mail"
        v-model="user.email"
        @input="isInput"
        class="border-2 h-12 w-10/12 mb-5"
      />
      <p class="text-red-400">{{ emailErrorMassage }}</p>
      <input
        type="”password”"
        name="”password”"
        placeholder="password"
        v-model="user.password"
        @input="isInput"
        class="border-2 h-12 w-10/12 mb-5"
      />
      <p class="text-red-400">{{ passwordErrorMassage }}</p>
      <button
        @click="login"
        value="ログイン"
        class="h-12 w-10/12 my-4 bg-green-300 text-center"
      >
        ログイン
      </button>
      <button @click="googleLogin" class="h-12 w-10/12 my-4 bg-green-300">
        Googleでログイン
      </button>
    </form>
    <div class="tracking-widest items-center my-4">
      <a href="/singup" class="h-12 text-blue-500"
        >ユーザー登録お済みでない方</a
      >
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      user: {
        email: "",
        password: "",
      },
      emailErrorMassage: "",
      passwordErrorMassage: "",
    };
  },
  methods: {
    login() {
      if (this.user.email === "") {
        this.emailErrorMassage = "メールアドレスを入力してください";
      }
      if (this.user.password === "") {
        this.passwordErrorMassage = "パスワードを入力してください";
      }
      if (this.emailErrorMassage !== "" || this.passwordErrorMassage !== "") {
        return;
      }
      this.$auth
        .signInWithEmailAndPassword(this.user.email, this.user.password)
        .then((user) => {
          alert("ログイン成功しました！");
          this.$store.dispatch("confirmLogin");
          this.$router.push("/top");
        })
        .catch((error) => {
          console.log(error);
          alert("メールアドレスもしくはパスワードが異なります");
        });
    },
    isInput() {
      this.emailErrorMassage = "";
      this.passwordErrorMassage = "";
    },
  },
};
</script>
```
**未入力時、エラーメッセージに一致する部分がある時の処理(login)**

**firebase使用時の必須時効**
・`this.$auth.signInWithEmailAndPassword`はfirebaseを使用してのログイン機能を実装するときに**使用するルール**が決められている。

**正常に登録できた時の処理(.then)**
・新規登録時の処理と同様

**エラー発生時の処理(.catch)**
・アラートにてメールアドレスもしくはパスワードが異なることを通知。

#ログイン成功時

![スクリーンショット 2021-12-25 21.57.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2114750/920a7a97-c128-ed74-ead8-d29127a13fed.png)


#エラー発生時

![スクリーンショット 2021-12-25 21.57.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2114750/9e5a0f81-eea8-f1ec-e875-4222432dc56b.png)

#まとめ
今回は新規登録・ログインのstoreの保持/管理、正常に登録できた時/エラーが起きた時の処理の実装を記事にしました。次回に、
・firebase×Googleアカウントでのユーザー新規登録、ログインの実装

についてQiitにまとめていきます！

今回の記事を読んで質問、間違い等あればコメント等頂けると幸いです。

長くなりましたが、最後までご愛読ありがとうございました！