今まで起きたエラーを管理するアプリ作ってみた

フロントをReact、サーバーサイドをNode、Expressで作成しました。

DBとしてFirebase Cloud Firestoreを使用し、フロントをFirebase Hosting、サーバーをHerokuにデプロイしました。

# 作ったアプリについて

私は現在エンジニアとしてインターンを２年間やっており、エラーが出たときに「このエラーどっかで見たなぁ」みたいなことが最初の頃よくありました。

今回はこのようなことを解消するためのアプリを作成しました。

## 使用方法

1. 起きたエラーを入力
1. カテゴリーを選択（React,Nodeなど）
1. 解決できているならば参考になったURLを記入
1. メモを書く

という流れになります。


今までに起きたエラーを蓄積していくことで、もし同じエラーが起きた場合は、エラーを入力した際に知らせてくれて再び解決策を探す作業が省くことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483460/3b2ff812-58e5-43ca-c03b-87e32db5485a.png "ホーム画面")

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483460/c718b88c-be2c-012a-6d2e-836ed125c414.png "エラーの詳細表示")

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483460/3e6103b1-5f11-c81c-037c-a721ac943e5a.png "アカウントページのカテゴリー編集画面")

こちらが作ったアプリ( [Error Manager](https://errormanager-ec40d.web.app/) )になりますが

現在はサインアップを実装しておらず、私だけが使えるテスト段階です。

# 詰まったところ

## Reactでのログイン認証

色々と調べたところ、しっかりとしたアプリならばセキュリティを考慮して自分でログイン認証を作成するべきではなく、Auth0などのサービスを使用したほうがいいというのが結論でした。

ただ、今回のような小規模な重要な情報を保持しないアプリであれば、LocalStorageやCookieを使って実装してもよいという意見もあり、CookieとFirebase Authenticationで実装しました。

Firebase Authenticationでログイン認証を行い、ログインしたらCookieにID、Passwordを保持し、ログアウトしたらCookieのID、Passwordを削除するという方法になります。

Firebase Authenticationのログイン認証の実装に関しては[公式のドキュメント](https://firebase.google.com/docs/auth/web/start?hl=ja)がわかりやすいので詳しい設定はこちらを参考に。

サインイン画面でSubmitボタンを押すと、以下のsigninFunc()が動き、
signInWithEmailAndPasswordでFirebase Authenticationの認証が成功したらCookies.setでemail、password、uid（Firebase Authentication側で勝手に割り振られるID）をCookieに書き込みます。
認証失敗したらEmailもしくはPasswordが間違っている可能性があることをユーザーに知らせます。
Cookieを操作するライブラリは[js-cookie](https://www.npmjs.com/package/js-cookie)を使用しました。

```javascript:signin.js
  const signinFunc = () => {
    const email = document.getElementById("email").value
    const password = document.getElementById("password").value
    firebase.auth().signInWithEmailAndPassword(email, password)
    .then((user) => {
      setOpenErr(false)
      setOpenSuc(true)
      Cookies.set("email",email,{"expires":7})
      Cookies.set("password",password,{"expires":7})
      Cookies.set("uid",user.user.uid,{"expires":7})
      document.location = "/"
    })
    .catch((error) => {
      setOpenErr(true)
      var errorMessage = error.message;
      console.log(errorMessage)
    });
  }
```

ログイン認証後は、Cookieにあるemail、password、uidを使ってホーム画面に遷移する際に認証します。


```javascript:App.js
import './App.css';
import SignIn from './pages/signIn';
import SignUp from './pages/signUp';
import Main from './pages/main'
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import Auth from './components/Auth';

function App() {
  return (
      <BrowserRouter>
        <Switch>
          <Route path="/signin" component={SignIn}/>
          <Auth>
            <Switch>
              <Route path="/" exact component={Main} />
            </Switch>
          </Auth>
        </Switch>
      </BrowserRouter>
  );
}

export default App;
```

```javascript:User.js
import Cookies from 'js-cookie'
import firebase from '../firebase/firebase'

export function isLoggedIn(){
    const email = Cookies.get("email")
    const password = Cookies.get("password")
    if(!(email && password)) return false
    const isLogin = firebase.auth().signInWithEmailAndPassword(email, password)
    .then((user) => true)
    .catch((error) => {
      const errorMessage = error.message;
      return false
    });
    return isLogin;
}

export function logoutFunc(){
  Cookies.remove("email")
  Cookies.remove("password")
  Cookies.remove("uid")
  document.location = "/signin"
}
```

ログインしていないとホーム画面に遷移できないようにする方法は[こちら](https://qiita.com/ginban22/items/a36d01b41deaeedd581e)の記事を参考にしました。


## Firebase Hositingの方法（自分用メモ）

変更した際に、デプロイする方法をいつも迷ってしまうのでメモ。

```powershell
npm run build

firebase deploy --only hosting
```

このあと、ブラウザのキャッシュをクリア