Firebaseの技術を使ってWebページをもう少し進化させる

今回、FirebaseのRealtime DatabaseとCloud Storageの仕組みを使って今までのwebページの機能を増やしました。

Firebaseの全体図と各機能の理解については
以下が非常に参考になりました。
https://www.topgate.co.jp/firebase01-what-is-firebase

#Firebaseとは
Firebase は Google が提供しているモバイルおよび Web アプリケーションのバックエンドサービスです。クラウドサービスの形態では BaaS に位置付けされます。 Firebase を使うことで、バックエンドで動くサービスを作成する必要も管理する必要がなくなり、開発者はアプリケーションの開発に専念できます。

#Realtime Databaseとは
Firebase に元から含まれているオブジェクト型のデータベースです。リアルタイムでクライアント全体の状態を同期させることができ、オフラインで動作するときはデータをキャッシュしてオンラインになった時に自動的にデータを同期します。

#Cloud Storage for Firebaseとは
写真や動画などバイナリーデータを保存します。保存先は Cloud Storage となっており、 Firebase と Google Cloud の両方からアクセスできます。また、スケールアウト機能も兼ね備えており、急激なアプリケーションの拡大にも対応しています。

#公開Webページ
https://3dblock.jp

#今回追加した機能
<b>①ログインフォーム</b>
![ブロックで遊ぼう-Google-Chrome-2020-05-28-03-19-04.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612352/0b8f27be-dd63-3188-251f-af278ad0400a.gif)


<b>②画像投稿ページ</b>

![Voxel-Ant-_-あなただけのブロックアートを。-Google-Chrome-2020-05-28-03-26-59.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612352/a80d1898-e8fc-d059-9573-a22dac7ab36d.gif)


#コード
<b>HTML</b>

```html:index.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="utf-8">
    <title>Voxel Ant | あなただけのブロックアートを。</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
    <link rel="stylesheet" href="main.css">
</head>
<header>
    <link rel="stylesheet" href="main.css">
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <h1>
        <a href="index.html"><img src="ant-logo4.png" alt="街を作ろう"></a>
    </h1>
</header>

<body>
    <section id="loading" class="view">
        <i class="initial-loading-icon fas fa-sync" aria-hidden="true"></i>
    </section>
    <div id="logo-gazo">
        <img src="ant-logo3.png">
    </div>
    <!-- /#ログイン画面 -->

    <section id="login" class="view">
        <div class="container">
            <div class="row justify-content-center">
                <div class="col-sm-10 col-md-8 col-lg-6">
                    <form id="login-form">
                        <div class="form-group login__email">
                            <label for="login-email" class="col-form-label">
                                メールアドレス
                            </label>
                            <div>
                                <input id="login-email" type="email" class="form-control" required>
                            </div>
                        </div>
                        <div class="form-group login__password">
                            <label for="login-password" class="col-form-label">
                                パスワード
                            </label>
                            <div>
                                <input id="login-password" type="password" class="form-control" required>
                            </div>
                        </div>
                        <div id="login__help" class="alert alert-danger"></div>
                        <div class="form-group login__submit">
                            <div>
                                <button id="login__submit-button" type="submit" class="btn btn-success">
                                    ログイン
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </section>
    <!-- /#ログイン画面 -->

    <!-- 一覧画面 -->
    <section id="blcokgallery" class="view">
        <header>
            <div id="header">
                <a href="#add-block-modal" data-toggle="modal" class="add-button">
                    <i class="fas fa-plus-circle" aria-hidden="true"></i> ブロックアートの登録
                </a>
                <button class="btn btn-primary logout-button">
                    ログアウト
                </button>
            </div>
        </header>
        <div id="cover">
            <h1 id="cover__title">ブロックアートギャラリー</h1>
        </div>
        <div class="wrapper">
            <div id="main">
                <div id="block-list" class="clearfix"></div>
            </div>
        </div>
    </section>

    <div id="block-template">
        <div class="block-item">
            <div class="block-item__image-wrapper">
                <img class="block-item__image" alt="">
            </div>
            <div class="block-item__detail">
                <div class="block-item__title"></div>
                <div class="block-item__delete-wrapper">
                    <button class="btn btn-danger block-item__delete">
                        <i class="fas fa-trash-alt" aria-hidden="true"></i>
                    </button>
                    <div id="good">
                        <button-preference></button-preference>
                    </div>
                    <script src="sub1.js"></script>
                </div>
            </div>
        </div>
    </div>

    <div id="add-block-modal" class="modal fade" tabindex="-1" role="dialog">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h4 class="modal-title">ブロックアートの登録</h4>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body m-1">
                    <form id="block-form">
                        <div class="form-group row">
                            <label for="add-block-title" class="col-md-3  col-form-label">タイトル</label>
                            <div class="col-md-9">
                                <input id="add-block-title" type="text" class="form-control" required>
                            </div>
                        </div>
                        <div class="form-group row">
                            <div class="col-md-3">アート画像</div>
                            <div class="col-md-9">
                                <div class="custom-file">
                                    <input id="add-block-image" type="file" accept=".jpg,.jpeg,.png,.gif, image/jpeg,image/png,image/gif" class="custom-file-input" required>
                                    <label id="add-block-image-label" class="custom-file-label" for="add-block-image">ファイルを選択</label>
                                </div>
                            </div>
                        </div>
                        <div id="add-block__help" class="alert alert-danger"></div>
                        <button id="submit_add_block" type="submit" class="btn btn-default btn-success btn-block">
                            保存する
                        </button>
                </div>
                </form>
            </div>
        </div>
    </div>

    <script src="https://www.gstatic.com/firebasejs/6.2.0/firebase-app.js"></script>
    <script src="https://www.gstatic.com/firebasejs/6.2.0/firebase-auth.js"></script>
    <script src="https://www.gstatic.com/firebasejs/6.2.0/firebase-database.js"></script>
    <script src="https://www.gstatic.com/firebasejs/6.2.0/firebase-storage.js"></script>
    <script>
        const firebaseConfig = {
            apiKey: "HOGEHOGE",
            authDomain: "HOGEHOGE",
            databaseURL: "HOGEHOGE",
            projectId: "HOGEHOGE",
            storageBucket: "HOGEHOGE",
            messagingSenderId: "HOGEHOGE",
            appId: "HOGEHOGE",
            measurementId: "HOGEHOGE"
        };
        firebase.initializeApp(firebaseConfig);
    </script>
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
    <script src="main.js"></script>
</body>

</html>
```

#補足
以下については自身のAPIキー等に置き換えてください。

```
    <script>
        const firebaseConfig = {
            apiKey: "HOGEHOGE",
            authDomain: "HOGEHOGE",
            databaseURL: "HOGEHOGE",
            projectId: "HOGEHOGE",
            storageBucket: "HOGEHOGE",
            messagingSenderId: "HOGEHOGE",
            appId: "HOGEHOGE",
            measurementId: "HOGEHOGE"
        };
        firebase.initializeApp(firebaseConfig);
```

#参考にした記事・リンク

<技術編>
- https://www.topgate.co.jp/firebase01-what-is-firebase
- https://firebase.google.com/docs/database/web/read-and-write?hl=ja
- https://firebase.google.com/docs/database/web/save-data?hl=ja

<独自ドメインでの公開>
- 爆速！Vercelとfreenomで独自ドメインのサイトを無料で作成する
https://qiita.com/n0bisuke/items/901154531ea14f978bd4


#終わりに
- 今回、時間がなく出来ませんでしたが、本当はAI技術を組み合わせた実装にも挑戦してみたかったです。