Vue.js + FirebaseでToDoアプリを構築

todo機能の作成

realtime databaseの作成

firebaseのrealtime databaseはデータをアプリケーションとリアルタイムで同期することが可能。
今回はtodoアプリのタスク情報を保存するのに使用する

vueのメインページにてタスクを作成・削除を行う機能を実装する。
vue-todo/src/components/Task.vue

<template>
  <div class="task">
     <h2>タスク</h2>
    <div>
      <input type="text" v-model="newTodoName">
      <button type="submit" v-on:click="createTodo()">タスク作成</button>
    </div>
    <ul>
      <li><button type="submit" v-on:click="showTodoType = 'all'">すべて</button></li>
      <li><button type="submit" v-on:click="showTodoType = 'active'">未完タスク一覧</button></li>
      <li><button type="submit" v-on:click="showTodoType = 'complete'">完了タスク一覧</button></li>
    </ul>
    <!-- todoの一覧表示 -->
    <ul v-for="(todo, key) in filteredTodos" :key="todo.id">
      <li><input class="toggle" type="checkbox" v-model="todo.isComplete" v-on:click="updateIsCompleteTodo(todo, key)">{{ todo.name }}</li>
      <button type="submit" v-on:click="deleteTodo(key)">削除</button>
    </ul>
  </div>
</template>

<script>
import firebase from "firebase";

export default {
  name: "Task",
  data() {
    return {
      database: null,
      todosRef: null,
      newTodoName: "",
      showTodoType: "all",
      todos: []
    };
  },
  created: function() {
    this.database = firebase.database();
    this.uid = firebase.auth().currentUser.uid;
    this.todosRef = this.database.ref("todos/" + this.uid);

    var _this = this;
    // データに変更があると実行されるfunction
    this.todosRef.on("value", (snapshot) => {
      this.todos = snapshot.val(); // 再取得してtodosに格納する
    });
  },
  computed: {
    // フィルターの実装showTodoTypeが変更されると実行される
    filteredTodos: function() {
      if (this.showTodoType == "all") {
        return this.todos;
      } else {
        var showIsComplete = false;
        if (this.showTodoType == "complete") {
          showIsComplete = true;
        }
        var filterTodos = {};
        for (var key in this.todos) {
          var todo = this.todos[key];
          if (todo.isComplete == showIsComplete) {
            filterTodos[key] = todo;
          }
        }
        return filterTodos;
      }
    }
  },
  methods: {
    // DBのtodos/[uid]/以下にデータを格納していく
    createTodo: function() {
      if (this.newTodoName == "") {
        return;
      }
      this.todosRef.push({
        name: this.newTodoName,
        isComplete: false
      });
      this.newTodoName = "";
    },
    // 完了・未完了の値の更新
    updateIsCompleteTodo: function(todo, key) {
      todo.isComplete = !todo.isComplete;
      var updates = {};
      updates[key] = todo;
      this.todosRef.update(updates)
    },
    // todoの削除
    deleteTodo: function(key) {
      this.todosRef.child(key).remove();
    }
  }
};
</script>

<style>
</style>

実際にタスクを登録してみましょう
firebaseでデータの状態がリアルタイムに確認することができます。

DBのセキュリティ設定

現在のrealtime databaseの設定では他のユーザのデータも認証が通っていれば編集できてしまう。
そこでユーザごとにアクセスできるデータを制限したい。

現在 todos/[uid]/[todoデータ]というデータ構造になっているので、[uid]以下は
ログインしているユーザと一致している場合に編集権限を与えたいと思います。

firebaseのrealtime databaseではルールを設定することで簡単にアクセス制限を実現することができる

{
  "rules": {
    "todos": {
      "$user_id": {
        ".write": "$user_id === auth.uid",
        ".read" : "$user_id === auth.uid"
      }
    }
  }
}

firebase-cliを使ったdeploy

firebaseにはホスティング機能がついており作ったvueアプリケーションを簡単にインターネットに公開することができます。
「firebase-tools」を使えば簡単な設定でコマンドライン上からデプロイすることができて便利です。
firebase-toolsをインストールしてデプロイしてみましょう。

firebase-toolsのインストールと設定

ターミナルで以下のコマンドを実行していきます。

# firebase toolをインストール
npm install -g firebase-tools

# ログイン
firebase login

プロジェクトのディレクトリで以下を実行してfirebase-toolsにプロジェクトを登録します。

> firebase init  # プロジェクトディレクトリの中で実行                                  

     ???????? ???? ????????  ???????? ????????     ???     ??????  ????????
     ??        ??  ??     ?? ??       ??     ??  ??   ??  ??       ??
     ??????    ??  ????????  ??????   ????????  ?????????  ??????  ??????
     ??        ??  ??    ??  ??       ??     ?? ??     ??       ?? ??
     ??       ???? ??     ?? ???????? ????????  ??     ??  ??????  ????????

You're about to initialize a Firebase project in this directory:

  /Users/bun/Desktop/vue-todo-demo

? Which Firebase CLI features do you want to setup 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

カーソルをHostingに移動させてSpaceを押してチェックを入れた後Enterで次に進みます。

You're about to initialize a Firebase project in this directory:

  /Users/bun/Desktop/vue-todo-demo

? Which Firebase CLI features do you want to setup for this folder? Press Space to select features, then Enter to confirm your choices. Hosting: Configure and deploy Firebase Hosting sites

=== Project Setup

First, let's associate this project directory with a Firebase project.
You can create multiple project aliases by running firebase use --add,
but for now we'll just set up a default project.

? Select a default Firebase project for this directory:
  [don't setup a default project]
❯ vue-todo (vue-todo)
  Firebase Demo Project (fir-demo-project)
  vue-todo (vue-todo-a3b8b)
  [create a new project]

プロジェクトのディレクトリを聞かれるので「vue-todo」にカーソルを移動させてEnter

=== Hosting Setup

Your public directory is the folder (relative to your project directory) that
will contain Hosting assets to be uploaded with firebase deploy. If you
have a build process for your assets, use your build's output directory.

? What do you want to use as your public directory? dist
? Configure as a single-page app (rewrite all urls to /index.html)? Yes
✔  Wrote dist/index.html


次に公開用のディレクトリを聞かれるので「dist」と入力して Enter (vue-cliでプロジェクトを作成するとデフォルトの公開ディレクトリはdist)
最後にyと入力してEnter

これでプロジェクトの登録は終了です。

本番用ビルド

次にvue-cliでビルドを実行して、公開用ファイルを生成します。
dist以下にビルドされたファイルが追加されます。

firebase上にデプロイ

ターミナルで以下のコマンドを実行

> firebase deploy

firebaseのHostingメニューからURLを確認してアクセスしてみましょう。