Vue(Vuetify)＋FirebaseのAuthenticationでユーザー認証を実装した話（ユーザー登録編）

バックエンドの実装ばっかりで、フロント実装の経験がほぼなかったので、Vue(Vuetify)使ってフロントを実装してみた話です。

<details><summary>やり始めるまでの与太話。</summary>大まかな理由は先に書いた通りなんですが、現職の会社でフロントをTS（TypeScript）を標準にしていこうという流れや、サーバレスやらマイクロサービスやらワードが飛び交いはじめ・・・。
『・・・っ！？』ってなったので、『とりあえず作ろ♪』というノリ。  
・ TS＋Vueじゃないの？→TSの前にそもそもVueがわからなかったorz
・ なんでVue（Vuetify）なの？→今までVue使っている案件に入ることが多かったので。
・ なんでFirebase？→AWSでやりたかったけど、クレカ登録必要だったんですもの・・・。（でも、今年中にはやる）
でもFirebase思いのほか楽ちん過ぎてびっくりです。（本域）
</details>

# 環境
- Windows(10)
- Firebase
- Vue（2.6.14）
  - Vuetify（2.6.2）
  - router（）
  - Vue CLI（4.5.15）
- npm（8.4.1）
- node.js（16.13.0）

# 事前準備
- Firebaseの登録
- Vueプロジェクトの生成  
※上記は別途記事化します

# 手順
Vuetifyをインストールして`npm run serve`したものがコチラになります。（3分クッキング風）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1588937/7af159b0-c33e-d6fa-b9be-1285579281af.png" width="60%" border="1">

## firebaseインストール
Firebaseの公式から言われた通りに、firebaseのプラグインをインストールします。
コマンドプロンプトを開いて、対象のプロジェクトまで移動し、下記コマンドを実施してください。

```console
npm install firebase
```

## 対象のファイル作成
ちなみに、今回はメアド＋パスワードでユーザ登録をする方式で行っていきます。
上記のほかにも、Twitterアカウントなどのアカウントでもユーザー作成できるようです。

### 1. pluginsフォルダにfirebase.configの作成
Firebaseのプロジェクトを作成した際に表示されたConfigから初期化までを行うためのファイルを作成します。

- 配置先

```
{project_root}
    └ src
　　    └ plugins
　　　　　　└ firebaseConfig.js
```

- 中身

```js:firebaseConfig.js
import { initializeApp } from "firebase/app";

// firebaseから取得した値をコピペ
const firebaseConfig = {
  apiKey: "*****************",
  authDomain: "*****************",
  databaseURL: "*****************",
  projectId: "*****************",
  storageBucket: "*****************",
  messagingSenderId: "*****************",
  appId: "*****************",
  measurementId: "*****************"
};

// Initialize Firebase
const firebaseApp = initializeApp(firebaseConfig);
export default firebaseApp
```

### 2. routerのindex.jsのメンテ
今回はrouter使って画面遷移しているので、ここに画面遷移について追記します。

- ありか

```
{project_root}
    └ src
　　    └ router
　　　　　　└ index.js
```

- 改修内容

```js:index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'

Vue.use(VueRouter)

const routes = [
  { // ★「/」→「/home」に
    path: '/home',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  },
  { // ★「/」を追加し、Usersページへのルーティングを追加
    path: '/',
    name: 'Users',
    component: () => import('../views/Users.vue')
  }
]

const router = new VueRouter({
  routes
})

export default router
```


### 3. viewsフォルダにUsers.vueの作成

Scriptタグの中身は公式で公開されているソースコードほぼそのままです。
すごく親切。

- 配置先

```
{project_root}
    └ src
       └ views
　　　　　　└ Users.vue
```

-　中身

```vue:Users.vue
<template>
  <v-container>
    <v-row>
      <v-col cols="12">
        <v-text-field
            label="Email*"
            v-model="email"
        ></v-text-field>
        <v-text-field
            label="Password*"
            type="password"
            v-model="pw"
        ></v-text-field>
        <v-btn
          color="primary"
          @click="createUser()"
        >
            作成
        </v-btn>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
import firebaseApp from '../plugins/firebaseConfig'
import { getAuth, createUserWithEmailAndPassword } from "firebase/auth";

const auth = getAuth(firebaseApp)

export default {
  name: 'Users',
  data: () => ({
    email: '',
    pw: ''
  }),
  methods: {
    createUser: function () {
      createUserWithEmailAndPassword(auth, this.email, this.pw)
        .then((userCredential) => {
          const user = userCredential.user
          console.log('create user success.' + user)
          alert('作成成功')
        })
        .catch((error) => {
          const errorCode = error.code
          const errorMessage = error.message
          console.log('errorCode: ' + errorCode)
          console.log('errorMessage: ' + errorMessage)
          alert('作成失敗')
        })
    }
  }
}
</script>

```

### 4. 動作確認

たぶん問題ないと思いますが、`npm run serve`してたら、念のため一回再起動してみてください。

ブラウザを開いて、ページにアクセスします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1588937/7a530ec1-66be-aebb-a619-3749824580be.png" width="60%" border="5">

表示はよさそうです。

では、メアド・パスワードを入力し作成ボタンをクリックします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1588937/22d4b979-bb1c-45ac-859c-f27ff7936a44.png" width="60%" border="5">

どうやらユーザー作成に成功したようです。
Firebaseのコンソールも確認してみましょう。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1588937/d0ae1533-830b-03f4-beae-6957e47495e8.png" width="80%" border="5">

こちらにも登録されてますね。

# あとがき

Vuetify・Firebaseいいですね。  
デザインセンスのない私でもある程度整った画面が簡単に作れてしまうので、びっくりです。
これがマテリアルデザインってやつなんでしょうか。

FirebaseもCloud Messaging以外は初めて使用するのですが、めちゃくちゃ楽ちんですね。
初期化して、必要な情報渡すだけ選択の時に使用するジェルボールのようだ。（違）

余談ですが、`createUserWithEmailAndPassword`の処理を共通コンポーネントなどにするときは非同期で処理がされるので、`.then`とかに`return`を書いても値が取得できないです。

# 参考記事
- [Firebase公式：パスワード ベースのアカウントを作成する](https://firebase.google.com/docs/auth/web/password-auth?authuser=0)

# Github
- [firebase demo](https://github.com/beeeegle/firebase_demo)