Vue.js 使用 Firebase Realtime Database 作為資料庫解決方案

2021-07-18

筆記如何使用 Vue.js 結合 Firebase Realtime Database 讀取、新增以及刪除資料。

logo

環境準備

建立 Vue 專案

vue create vue-firebase

使用的 plugin 包括: vue-router、vuex、eslint (airbnb)、saas (dart-node)。

eslintrc.ts

eslint 在每次存檔的時候都會嚴格的提醒你源始碼有什麼問題,但為了提升程式碼的品質還是加入本次的專案使用,也藉由 eslint 的提示學習 js 的正確的語言使用習慣。另這次專案不斷被 eslint 抱怨 換行符號使用 CRLF,藉由調整 eslintrc.ts 加入下列規則關閉。

module.exports = {
  rules: {
    "linebreak-style": 0,
  },
};

安裝 Firebase SDK & VueFire

安裝 VueFire 及 Firebase SDK,但需要注意的是本次專案使用的是 Vue3 所以必須搭配使用新版本的 VueFire、Firebase。

npm install vuefire@next firebase@next

Firebase

圖片來源:firebase

建立專案

databaseURL 會在開發的時候用到,而整個 firebaseConfig 會在部署專案的時候使用。

設定權限

開發階段只做允許時間上的限制,日後要再加上 Authentication & Authorization。

Vue.js

main.js

因為是使用 Firebase 的 Realtime Database,所以要載入的是 rtdbPlugin,經使用 vue instance use 後掛載到 #app。

import { createApp } from 'vue';
import { rtdbPlugin } from 'vuefire';
import App from './App.vue';
import router from './router';
import store from './store';

const vue = createApp(App).use(store).use(router);
vue.use(rtdbPlugin);

vue.mount('#app');

建立 db.js

由於是在本機環境且搭配 Firebase 的開發寬鬆權限授予,所以僅需調整 Database Url 就可以讀寫 Realtime Database。

import firebase from 'firebase/app';
import 'firebase/database';

// eslint-disable-next-line import/prefer-default-export
export const db = firebase
  .initializeApp({ databaseURL: 'https://ProjectDatabaseUrl.firebaseio.com/' })
  .database();

Home.vue

template

<div style="margin: 0 auto;width: 300px;">
  <div v-for="(data, index) in documents" :key="index" style="text-align:left;">
    {{ data.qno.toString().padStart(4, '0') }} |
    {{ data.correct }} |
    {{ data.date }}
  </div>
</div>

<div> {{ this.getRandom }} </div>

<div style="margin-top:20px">
  <button @click="add" style="margin-right:20px">Add</button>
  <button @click="remove">Remove</button>
</div>

scripts

// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue';
import Chance from 'chance';
import { db } from '../db';

const getRandomBool = () => {
  const c = new Chance();
  return c.bool();
};

const getRandomInt = () => {
  const c = new Chance();
  return c.integer({ min: 1, max: 9999 });
};

export default {
  name: 'Home',
  data() {
    return {
      documents: [],
    };
  },
  firebase: {
    documents: db.ref('tests/commits'),
  },
  components: {
    HelloWorld,
  },
  methods: {
    // 獨立抽出
  },
};

methods

add() {
  db.ref(`tests/commits/${this.documents.length.toString()}`)
    .set({
      date: `${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()}`,
      qno: getRandomInt(),
      correct: getRandomBool(),
    })
    .then(() => {
      console.log('data added');
    });
},
remove() {
  db.ref(`tests/commits/${(this.documents.length - 1).toString()}`)
    .remove()
    .then(() => {
      console.log('data removed');
    });
},

成果

參考資料

Build Todo List With Vuejs, Vuex, Vuetify and Firebase 🔥