[Vue.js][Vue3] Firebaseと連携させてFirestoreのデータを取得するサイトをつくる

みんなのITもくもく会】自己紹介 Advent Calendar 2020」参加記事ですー!

さいきんちょくちょく参加させて頂いている みんなのもくもく会

良い感じで平日の朝に個人開発を進める習慣が身に付いてきております。

主催されている Asukaさん (@asuka4624254)  に感謝!🙏

さて、昨日は、 あーたんさんの ダイレクトメール(DM)送付の停止について|あーたん|note という記事でした。

これ、Eメールにも言えますねぇ…。

 

さてさて、本日の記事は、Vue.js 3系で Firestore のデータを取得する、という初歩的な記事でございます。

背景

ちょっとしたネタサイトを作りたいと思ったのですが、

  • データは管理者である自分のみが更新できればOK。
  • ログイン機能なし、↑自分が用意した可変データを表示するのみ

という構成。よって、 Vue.js + Firebase でつくります。(Vue2系は触っていたので、今回 Vue3 に初チャレンジ。)

環境構築

↓こちらの記事を参考に、Vue-CLI をインストール。

Vue CLI 3の変更点・使い方(vue-cliから@vue/cliにアップデート) – Qiita

以下の組み合わせを選択。

Vue CLI v4.5.9
? Please pick a preset:
Default ([Vue 2] babel, eslint)
Default (Vue 3 Preview) ([Vue 3] babel, eslint) 
> Manually select features

 Check the features needed for your project: 
(*) Choose Vue version
(*) Babel
( ) TypeScript
( ) Progressive Web App (PWA) Support 
(*) Router
( ) Vuex
(*) CSS Pre-processors
>(*) Linter / Formatter
( ) Unit Testing
( ) E2E Testing

? Choose a version of Vue.js that you want to start the project with 
2.x
> 3.x (Preview)

? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n) Y

? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): 
Sass/SCSS (with dart-sass)
> Sass/SCSS (with node-sass)
Less
Stylus

? Pick a linter / formatter config: 
ESLint with error prevention only 
ESLint + Airbnb config
ESLint + Standard config
> ESLint + Prettier

? Pick additional lint features: 
(*) Lint on save
>(*) Lint and fix on commit

? Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys)
> In dedicated config files
In package.json

? Save this as a preset for future projects? (y/N) N

 

Firebase との連携設定

Firebase でプロジェクト新規作成

適当にプロジェクト名を付けて新規作成します。

Firestore で新規コレクション作成

Firebase Console から Firestore の作成へ。

新しく「コレクション」と「ドキュメント」を追加して、テストデータを用意しておきます。

コレクション名: contents

フィールド:

  • body : 文字列
  • category : 文字列

として、適当にテスト用データを入力しておきます。

Firebase にログインする

まずは firebase-tools が使用できる状態かどうか確認を…。

firebase --version

でエラーが出るようならインストルールされていないので、

Firebase CLI リファレンス

を参考に、 firebase-tools をインストールしておきます。

npm install -g firebase-tools

firebase-tools が利用できるようになったら、コンソールからログインしておきます。

firebase login

で認証画面がブラウザ上で開かれるので、いつもの認証処理を行います。無事ログインできれば、

Waiting for authentication...

+ Success! Logged in as login_username@gmail.com

とコンソールに表示され、ログインが完了します。

Firebase のプロジェクト情報を読み取ってみる

firebase projects:list

とコンソールで打ち込むと、以下のように、作成済みのプロジェクト一覧が表示されます。

√ Preparing the list of your Firebase projects
┌───────────────┬───────────────┬────────┬───────────┐
│ Project Display Name         │ Project ID                   │ Project Number │ Resource Location ID │
├───────────────┼───────────────┼────────┼───────────┤
│ anotest                      │ anotest-2020                 │ 123456789012   │ asia-northeast1      │
├───────────────┼───────────────┼────────┼───────────┤
│ nuxt-firebase-project-202009 │ nuxt-firebase-project-202009 │ 123456789012   │ asia-northeast1      │
└───────────────┴───────────────┴────────┴───────────┘

2 project(s) total.

このとき、該当のプロジェクトIDをメモっておきます。

プロジェクトで Firebase 用の設定初期化を実行する

プロジェクトルートに移動して、

firebase init --project=myproject-id

を実行すると、

? Are you ready to proceed?

「本気か?」と聞かれるので Y と答えます。

どの機能を使う気かチェックしろ、と言われるので、今回は Firestore と Hosting をチェックして次へ。

? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices. 
( ) Database: Deploy Firebase Realtime Database Rules
>(*) Firestore: Deploy rules and create indexes for Firestore
( ) Functions: Configure and deploy Cloud Functions
(*) Hosting: Configure and deploy Firebase Hosting sites
( ) Storage: Deploy Cloud Storage security rules
( ) Emulators: Set up local emulators for Firebase features
( ) Remote Config: Get, deploy, and rollback configurations for Remote Config

次に Firestore 関連の質問が2~3ありますが、そのままリターンを押して、デフォルトのままで進みます。

Hosting の質問が出てきたらちょっと注意。

↓この質問のデフォルトが public になっているので、 dist に変更。

? What do you want to use as your public directory? dist

また、 push した時に自動的に deploy されるようにするなら、

? Set up automatic builds and deploys with GitHub? (y/N) y
? Set up the workflow to run a build script before every deploy? Yes
? What script should be run before every deploy? (npm ci && npm run build)
? Set up automatic deployment to your site's live channel when a PR is merged? (Y/n) Y

とすれば良さそうです。(最後のはデフォルトのまま)

Firebase ライブラリの導入

公式に沿ってライブラリを導入します。

npm i firebase

各種キーをセットするんですが、「FirebaseのAPIキーは公開しても大丈夫」と言われても、公開せずに運用できるならその方が安心な訳で。

GitHub にソース公開する場合を想定して、環境変数は .env に分けます。

.env

VUE_APP_PROJECT_NAME="MY SUPER PROJECT"
VUE_APP_URL="https://example.com/"
VUE_APP_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
VUE_APP_AUTH_DOMAIN="example.firebaseapp.com"
VUE_APP_DATABASE_URL="https://example.firebaseio.com"
VUE_APP_PROJECT_ID="example-project-id"
VUE_APP_STORAGE_BUCKET="example.appspot.com"
VUE_APP_MESSAGING_SENDER_ID="999999999999"
VUE_APP_AP_ID="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
VUE_APP_MEASUREMENT_ID="xxxxxxxxxxxx"

.js 側では process.env を使って参照します。

src/firebase/firebase.js というファイルを自前で作成しまして、イニシャライズ処理を組み込んでおきます。

import firebase from "firebase";

const settings = { timestampsInSnapshots: true };

const config = {
  apiKey: process.env.VUE_APP_API_KEY,
  authDomain: process.env.VUE_APP_AUTH_DOMAIN,
  databaseURL: process.env.VUE_APP_DATABASE_URL,
  projectId: process.env.VUE_APP_PROJECT_ID,
  storageBucket: process.env.VUE_APP_STORAGE_BUCKET,
  messagingSenderId: process.env.VUE_APP_MESSAGING_SENDER_ID,
  appId: process.env.VUE_APP_AP_ID,
  measurementId: process.env.VUE_APP_MEASUREMENT_ID
};

console.log(config); // 参照出来ているかの確認用

firebase.initializeApp(config);

firebase.firestore().settings(settings);

export default firebase;

DB参照したい .vue ファイルにて

import firebase from “@/firebase/firebase";

して、

created() {
    this.db = firebase.firestore();
},

のような形で参照します。(実際のデータ取得は下の方で)

(未解決)GitHub Actions でデプロイすると環境変数が参照できない

さて、 Git push → 自動でデプロイ、ができると楽かなー、と思って Firebase Project の導入時に、

? Set up automatic builds and deploys with GitHub? (y/N) y

を選択したのが、ここで仇になります😢

.env が GitHub 上にないため、GitHub Actions で 自動Deploy した場合に環境変数が取得できず、うまく動きません…。

この件につきましてはちょっと保留中…。

手動で

firebase deploy

コマンドを発行すると動くので、取り敢えず良しとしておきます🙏

VueFire 導入に失敗

さて、 Firebase との連携なので、VueFire を使うことにします。

公式サイトの手順に沿ってインストール…

と思ったら、 npm run serve はエラー無しで立ち上がったものの、画面が真っ白!

Chrome のデベロッパーツールを確認したらコンソールにこんなエラーが。

Uncaught TypeError: Cannot set property '$unbind' of undefined

ネットをさまよった結果、

Note: This version currently supports Vue 2 and Firebase 7. Support for Vue 3 / Composition API and Firebase 8 is on the way.

と書かれていたことに気づくのでした。「 Support for Vue 3… 」の部分だけ読んで、「あ、大丈夫ね!」って思ってましたよ、ムキーーッ。英語力の無さ!

と言う訳でこの記事を書いてる時点では、Vuefire は まだ Vue 3.x 系には対応していないのでした。

自前で Firestore にアクセス

気を取り直して、導入済みの firebase ライブラリを使ってアクセスすることにします。

こんな感じで、抽出しつつデータの取得が出来ます。

<template>
  <div class="home">
    <ul>
      <li v-for="content in contents" :key="content.body">
        category : {{ content.category }} / body :
        {{ content.body }}
      </li>
    </ul>
  </div>
</template>

<script>
import firebase from "@/firebase/firebase";

export default {
  name: "Home",
  data() {
    return {
      contents: [],
      db: null
    };
  },
  created() {
    this.db = firebase.firestore();
    this.syncContent();
  },
  methods: {
    syncContent() {
      const category = "normal"; // normal カテゴリーのみを対象とする
      this.contents.splice(0); // クリア
      this.db
        .collection("contents")
        .where("category", "==", category)
        .get()
        .then(querySnapshot => {
          querySnapshot.forEach(doc => {
            console.log(doc.data().body);
            this.contents.push(doc.data());
          });
        }, this.contents)
        .catch(function(error) {
          console.log("ERROR: ", error);
        });
    }
  }
};
</script>

 

無事、表示されました↓

 

さて、明日は (ヘビク)イワシさん (@sardine_bird)  の「
LINE Botに初挑戦予定なのでそれのこと or インスタからAPI経由で情報を抜くやり方 のどちらか」の予定です。楽しみ!