React応用 - PartX2 - FirebaseのFirestoreデータを表示してみる

# 目次

# React + Typescript環境作成

Git Bashを開いて、プロジェクトを作成するディレクトリまで移動し、下記コマンドを入力＆実行します。
(私は、C:\ReactStudyに移動しました。プロジェクト名をreact-firebase-testとしました。)

```typescript
npx create-react-app プロジェクト名 --template typescript
```

上記コマンドが終了しましたら、プロジェクトフォルダに移動し、
下記コマンドで初期画面が起動することを確認しておいてください。

```typescript
npm start
```

※Reactマークがあり、Learn Reactと書かれた画面です。

# 各種ツールのインストール

プロジェクトフォルダで下記コマンドを実行していきます。

#### material-ui/core

```typescript
npm i @material-ui/core
```

#### material-ui/icons

```typescript
npm i @material-ui/icons
```

#### firebase

```typescript
npm i firebase
```

#### react-router-dom

```typescript
npm i react-router-dom @types/react-router-dom
```

#### 初期画面の起動確認

再度、`npm start`で初期画面の起動を確認します。
が、コンパイルエラー画面が出ました。

<img width="90%" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/6527f87a-e943-259f-01fb-e0f5f795b8fd.png">

型を指定してないので、any型になるのでダメダメと言っているようです。
typescriptのコンパイラオプションを設定し切り抜けます。
tsconfig.jsonに`"noImplicitAny": false`を追加すれば、
無事、初期画面が起動するかと思います。

# Firebaseアカウントの作成

Sparkプラン（無料枠）でアカウント作成しておきます。
Googleアカウントがあれば簡単に作成できるかと思います。

#### `https://firebase.google.com/pricing?hl=ja`

# Firebaseプロジェクトの作成

- Firebaseコンソールで`プロジェクトを追加`をクリック
- プロジェクト名を入力し続行ボタンをクリック。※プロジェクト名は`ReactFirebaseTest`としました。
- Googleアナリティクスは有効にせず、プロジェクトを作成ボタンをクリック
- ウェブアプリにFirebaseを追加。※アプリのニックネームもプロジェクト名と同じにしました。また、`このアプリの Firebase Hosting も設定します。`はチェックを付けませんでした。
- コンソールにすすむボタンをクリック
- プロジェクト概要右横の歯車をクリックし`プロジェクトを設定`をクリックします。
- マイアプリの`SDK の設定と構成`部分の構成ラジオボタンをクリックします。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/0d856ace-69c8-83c4-92f1-2314a66903e6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/087385f9-d0d7-5466-c7eb-b82ce396e8f1.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/fa7eca85-8e06-fe39-1533-f313fcb0710f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/5a7c8281-5f0a-86bd-4789-aa90ce1c83cf.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/4fa236e8-2a3e-90a4-7544-1b31d2277253.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/ca8b1144-14b7-e3a5-523b-817a026a40c6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/c9b22576-2335-7f47-250f-e04a0077ef95.png)

# ReactとFirebaseの連携(.env)

VSCodeに戻り、Reactプロジェクト直下に`.env`ファイルを作成します。
右辺は、先ほどFirebaseの構成で確認した値を設定します。
※REACT_APP_DATABASE_URLは、下記例に習い、`https://プロジェクトID.firebaseio.com`とします。プロジェクトIDの部分を変更してください。

```typescript
REACT_APP_API_KEY=""
REACT_APP_AUTH_DOMAIN=""
REACT_APP_DATABASE_URL="https://プロジェクトID.firebaseio.com"
REACT_APP_PROJECT_ID="プロジェクトID"
REACT_APP_STORAGE_BUCKET=""
REACT_APP_MESSAGING_SENDER_ID=""
REACT_APP_APP_ID=""
```

# ReactとFirebaseの連携(firebase.ts)

Firebaseとの連携を行うソースファイル`firebase.ts`をsrcフォルダに作成します。

```typescript:firebase.ts
import firebase from "firebase/app";
import "firebase/app";
import "firebase/firestore";
import "firebase/auth";

const firebaseApp = firebase.initializeApp({
  apiKey: process.env.REACT_APP_API_KEY,
  authDomain: process.env.REACT_APP_AUTH_DOMAIN,
  databaseURL: process.env.REACT_APP_DATABASE_URL,
  projectId: process.env.REACT_APP_PROJECT_ID,
  storageBucket: process.env.REACT_APP_STORAGE_BUCKET,
  messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID,
  appId: process.env.REACT_APP_APP_ID,
});

export const db = firebaseApp.firestore();
export const auth = firebaseApp.auth();
```

App.tsxを書き換えます。

```typescript:App.tsx
// mod start
// import React from "react";
import React, { useState, useEffect } from "react";
// mod end

// add start
import { db } from "./firebase";
// add end

//  del start
// import logo from './logo.svg';
// import './App.css';
// del end

function App() {
  // add start
  const [users, setUsers] = useState([{ id: "", username: "" }]);

  useEffect(() => {
    const unSub = db.collection("users").onSnapshot((snapshot) => {
      setUsers(
        snapshot.docs.map((doc) => ({
          id: doc.id,
          username: doc.data().username,
        }))
      );
    });
    return () => unSub();
  }, []);
  // add end

  return (
    <div className="App">
      {/* add start */}
      {users.map((user) => (
        <h3>{user.username}</h3>
      ))}
      {/* add end */}
      {/* dell start */}
      {/* <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.tsx</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header> */}
      {/* dell end */}
    </div>
  );
}

export default App;
```

# Firebaseにデータを作成

`Firestore Database` と `Realtime Database` がありますが、今回は、`Firestore Database`を使用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/e74ea496-0e01-4f43-8624-36b526d72ba4.png)

データベースの作成をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/630559ee-551d-568b-6b38-da2a2ab56f82.png)

本番環境モードで開始するを選択し、次へをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/a23deaa4-6d61-75da-26c2-7ae03f7bd1df.png)

有効にするをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/2642dcdb-d1ed-f7e2-ae97-2de49d0d5753.png)

コレクションを開始をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/5a6777bc-9c1a-5130-2086-c60de748dfa5.png)

コレクションIDを入力し次へをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/46e2c8e9-db5e-6205-f467-57f25eca4d78.png)

ドキュメントIDは自動で設定し、フィールドと値を入力し保存をクリックします。
同様のユーザデータを複数用意しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/bd633daf-a9e2-12a8-9d1e-e71f405367a5.png)

# 動作確認(とりあえずyarn start)

タイトル通り、`yarn start`してみます。
### <font color="red">が、何も表示されません。</font>

いろいろ調べました。そして、環境を何度も作りなおしました。
`processis not defined`っていうエラーが。。。
Firebaseの環境変数が読み込めてない。っていうか、そのエラーでレンダリングする項目も読み込まれてません。

んで、解決策は

```typescript
yarn add dotenv
```

の後、

```typescript
npm install --save dotenv
```

で出来ました。よく分かりません。

プロジェクトにdotenvモジュールを持ってきて、インストールしてって感じなんでしょうか。。。

# 動作確認(再度チャレンジ)

`yarn start`!!!!

### <font color="red">ダメです。今度は、こんなエラーが出てました。</font>

`Uncaught Error in snapshot listener: FirebaseError: Missing or insufficient permissions.`

これはググったらすぐ分かりました。

Firestoreのルールタブのとこに記載されているルールの`write: if false`を`write: if true`にしたら

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/f2b4cb00-1dac-3c0e-5713-b78397ac7de7.png)

### 表示できたぁ！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/5d3aa09c-7524-68a3-fe1d-201585d07502.png)

# Firestoreにデータを追加

追加してみてください。
自動的にブラウザで表示していたデータが増えてますよね？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/a9c61586-12f5-e823-3694-3cb994c3caa2.png)