【再現度高】初学者がはまりがちなfirebaseの罠を簡単なTODOアプリで攻略

<h1>Firebaseの罠多すぎ問題</h1>
学習のため簡単なメモアプリをfirebase/firestoreを使って作成したものの、罠にはまり数日費やしたので初学者（僕）がはまりやすいところについて解説します。

<h2>罠一覧</h2>
<ul>
<li>そもそもver違いの情報が入り乱れており、他者の情報をもとにスクラッチでコードを書くと動かない</li>
<li>最小構成（JS+html）の情報が少なく、Vueやreact等が必要になり、フロントで躓きがち</li>
<li>意味も分からず、npm initしがち。jsonファイルをつい作ってしまう</li>
<li>公式が初学者には理解しづらく、SDKの案内でnpm i firebase しがち</li>
<li>上記とともに、export、require、importしようとしがち</li>
<li>publicフォルダがよくわからず、アプリがデプロイできない</li>
<li>htmlの名前をindex.htmlにしていない</li>
<li>公式の情報は今回はfirebaseのconfig設定くらいしか使いません。下手にコピペすると動かんのよね</li>
</ul>

<h2>□環境</h2>
■開発環境
<ul>
<li>windows10pro</li>
<li>Vs code</li>
<li>node js</li>
<li>Git bash</li>
</ul>

■使用ライブラリ
<strong>なし！</strong>
★罠
nodeもfirebaseのインストールもいりません。
公式の通りにやると、npm i firebaseをやりがちですが不要です。
またnpm installでjson作りたくなりがちですが、まったくいりません。
デプロイに際してインストールの必要があるものがありますが、それまでは何もいりません。

■フォルダ構成
★罠
◇アプリのフォルダの直下にpublicフォルダを作り、
その直下にデプロイしたいアプリを置くこと。
※デプロイ時は設定をしない場合publicフォルダが使われます。
publicフォルダがない場合フォルダが勝手に作られ、
firebase hostingへの案内しかできないアプリと化します。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/650652/8910337a-3791-9728-cf44-8615505fcba5.png)

<h2>□作業手順</h2>
<h3>firebaseの設定</h3>
①firebaseにログイン（googleアカウントがそのまま使えます）

②使ってみるをクリック
③プロジェクトを追加をクリック
④プロジェクト名をつける（他人と重複できないので、やや複雑目な名前を付けること）
⑤アナリティクスは無視して、続行をクリック
⑥アカウントを選択（default acount for firebase)しプロジェクトを作成をクリック
⑦プロビジョニングで3分ほど待つ
⑧⑦が終わったら続行をクリック

<h4>firestoreの設定</h4>

⑨左上の設定ボタンから、すべてのプロダクトを選択する
⑩cloud firestoreをクリック
⑪データベースの作成をクリック
⑫テストモード（どっちでもいい）で開始するを選び次へをクリック
⑬ロケーションを「asia-northeast1」を選択し有効にするをクリック
⑭プロビジョニングで3分ほど待つ
⑮DBができたら、何にも触れず左上の歯車マークをクリックし、プロジェクトの設定をクリック
⑯マイアプリの＜/＞というマークをクリック
⑰アプリの登録という画面に切り替わるので、アプリのニックネーム（なんでもいい）をつけて、hostingの設定にチェックを入れる
⑱使えそうなドメイン名を入力し、アプリを登録をクリック
⑲SDKの追加のコマンドは無視し、const firebaseConfig = {}の中身だけコピペし、メモ帳にでも貼り付け次へをクリック
⑳いったん設定終わり

<h3>アプリを作る</h3>
htmlとjavascriptだけの簡単なTODOアプリになります。<br>
アプリ名のフォルダの直下にpublicという名前のフォルダを作り、その中にindex.htmlとapp.jsのファイルを作ってください。

firebaseのversionは現在9になっていますが、なぜだかうまく動かずはまったので、古いバージョン(8.10.1）を使用します。
よその情報をみると、色々もってきてますが、firebase-appとfirestoreだけでいいです。
とりあえず以下をコピーしてください。

````index.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>       
        <h1>Firestore-test</h1>
        Document名<input type="text" id="document">
        内容<input type="text" id="content">
        <button id="add-button">追加・内容変更</button>
        <button id="deleteData">削除</button><br>
        <div id="mainText">以下TODO<br></div>
        <script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-app.js"></script>
        <script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-firestore.js"></script>
        <script src="app.js"></script>
    </body>
</html>
````

公式で案内されますががexportやrequire、importはいりません（使えません）
詳しいことはちょっとしか知らないのですが、ローカルサーバを立てないと怒られ続けてはまります。12時間くらいはまりました。firebaseはapiサーバの構築をしないでデプロイできることもメリットなので、<strong>nodeやwebpackなどを使うのは、今じゃなくていいですよね！</strong>
というわけで今回は逃げます。

````app.js
//以下はfirebaseの設定をコピーして貼り付けてください。
const firebaseConfig = {
  apiKey: "",
  authDomain: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: "",
  appId: "",
  measurementId: ""
};
//ここまで貼り付け
firebase.initializeApp(firebaseConfig);
const db = firebase.firestore();
//ここまでfirebaseの設定 
window.onload = function(){
    viewData();
}
//追加・更新機能（set) 更新はドキュメント名を指定してコンテンツを更新
// 定例句：db.collection('DB名はここい書いたものが勝手に登録される').doc(documentData);
//ドキュメントはIDのこと。.docでID指定をできる※指定しないと勝手に降られる
const add = async () => {
    const contentData = document.getElementById('content').value;
    const documentData = document.getElementById('document').value;
    const docRef = db.collection('Users').doc(documentData);
    //docref(ドキュメントデータ)にコンテンツ（コンテンツデータ）を入れる。
    await docRef.set({
        content: contentData//ここではcontentとしているが、ここで決めたものがcolumn名となる。複数olumnも設定できる
    });
    contentData.innerText="";
    documentData.innerText="";
    location.reload();
    viewData();
}        
// 削除用のメソッド(delete)　ドキュメント名(ID)を指定して削除
//docでID指定。IDのvalueが合うものを削除。
const deleteData = async () => {
    const documentData = document.getElementById('document').value;
    await db.collection('Users').doc(documentData).delete();
    location.reload();
    viewData();
}
//表示用関数。
//読み取りメソッド(get)&for each
//docはIDのこと。コンソールログでdoc.id=docのID表示。doc.data()はdocの配列。.contentで中身指定
const  viewData=async ()=>{
    const snapshot = await db.collection('Users').get();
    snapshot.forEach((doc) => {
        const mainText = document.getElementById('mainText');
        const ID = document.createElement('span');
        const DATA =document.createElement('span');
        const BR =document.createElement('br');
        ID.innerText= doc.id+"=>";
        DATA.innerText= doc.data().content;
        mainText.appendChild(ID);
        mainText.appendChild(DATA);
        DATA.appendChild(BR);
        console.log(doc.id, '=>', doc.data());//テスト
    })   
}
document.getElementById("add-button").addEventListener("click", () => add());
document.getElementById("deleteData").addEventListener("click", () => deleteData());
````

とりあえず、ここまでコピーをして保存し実行をしてください。
おそらく、DBを使ったアプリができているはずです。

<h3>デプロイ</h3>
以下の順番でターミナルに入力してください。

````
npm install -g firebase-tools
````

````
firebase login
````

````
firebase init
````
firebase initでは、使用するサービスを聞かれます。
firestoreとhosting2種をスペースで選んでエンターを押してください。

Use an existing projectではさっき作ったDBがあるはずなのでそれを選ぶ。

あとはエンター連射です。
一か所、publicがどうのと聞かれる項目がありますが、これのおかげでpublicフォルダを先に作っておくと楽なわけです。
firebase jsonができていれば大体成功する。と思っています。なんでかはしらん。

````
firebase deploy
````
最後にfirebase deployコマンドを打つと、URLが出てきますので、コピペして飛びましょう。

<h2>最後に</h2>
自分がFBに触れる最初に出会えていたらなあ・・・という情報を記事にしてみました。
セキュリティの問題などもありそうで、nodeや.envなどを使ったほうがよさそうではありますが、とりあえずDBを使ったwebアプリをデプロイする！というだけが目的でしたらこの方法が最速でした。

サーバーサイドの入り口の予備知識としても優秀だと思います。

これを機にもう少しどっぷりサーバサイド方面に力を入れてみます。