本次要跟姊姊一起學習Vue 3 + Firebase Firestore database CRUD功能
▶ 如果您尚未建立專案/安裝 Firebase JS SDK 並初始化 Firebase,請先到
開箱23:Vue 3 + 建立web應用程式+Firebase JS SDK 初始化
▶ 若需要跳出的通知視窗,可參考
開箱15:輕鬆套用訊息通知UI~Vue 3 Toastify範例應用
今日步驟
參考 create , fetch , edit , delete (CRUD) Vue.js and Firebase Firestore database
https://www.youtube.com/watch?v=skaPoOhp4OI&ab_channel=benixal
官方文件:
了解 Cloud Firestore 收費方式:Understand Cloud Firestore billing
簡介:Cloud Firestore
該選擇哪一種資料庫? Cloud Firestore or Realtime Database
開始實作本次功能吧!

▲ 成果
Demo網址:https://hahasister-ironman-project.netlify.app/#/CRUD
版本 "firebase": "^10.4.0"
☆★☆★ 詳細程式碼 前往 >> 本次程式 commit 紀錄
功能大綱
-可新增/查詢/修改/刪除
結構
project-root/
├─ src/
│ ├─ views/
│ │ ├─ CRUD.vue // 新增操作頁面
│ │
│ ├─ services/
│ │ ├─ firebase.js // 引入
│ │
│ │
│ ├─ App.vue
│ ├─ main.js
└─ ...

可先以測試模式啟動(開通30天內-11/08,大家都可以讀寫資料庫)
安全規則選定後,接著會選資料庫要放在哪個地區,就可以先選預設
詳細可參考官方文件:
Cloud Firestore locations
完成之後可新增集合資料看看
Firebase Cloud Firestore 的資料架構有三層,Collections(每一個資料夾) > Documents(資料夾中每一份文件) > Data(文件中內容)。

詳細可參考官方資料模型:
Cloud Firestore Data model

輸入框 / 清單 / 編輯按鈕 / 刪除按鈕
<template>
  <div>
    <input type="text" v-model.trim="todo" @keyup.enter="create"/>
    <button type="button" @click="create">新增</button>
  </div>
  
  <div>
    <ul>
      <li v-for="item in todoList" :key="item.id">
        <input :id="item.id" name="todo" type="checkbox" v-model="item.status"
          @change="update(item)"/>
        <label :for="item.id">
          <input type="text" v-model="item.text" />
          <span>{{ timestampToCustomFormat(item.date) }}</span>
        </label>
        <div>
          <button type="button" @click.stop="update(item)">編輯</button>
          <button type="button" @click="remove(item.id)">刪除</button>
        </div>
      </li>
    </ul>
  </div>
</template>
並且修改 src/services/firebase.js
import { initializeApp } from 'firebase/app';
import { getFirestore } from 'firebase/firestore';  // 新增
const firebaseConfig = {
    ...
};
export const setupFirebase = () => {
  initializeApp(firebaseConfig);
};
// 初始化 Firebase
export const setupFirebase = initializeApp(firebaseConfig);
// 取得 Firestore 實例
export const db = getFirestore(setupFirebase); // 新增db匯出
詳細可看官方文件:Add data to Cloud Firestore
新增firebase的資料有兩種方法setDoc()、addDoc(),以下範例為使用addDoc()方法。
因爲有時文件(Documents)是沒有意義的ID,可以透過呼叫addDoc()方法來讓 Cloud Firestore 自動為您產生 ID 會更方便:
addDoc(collection(db, "集合的名稱")
<script setup>
import { db } from '@/services/firebase.js'; // 引入
import { collection,addDoc} from 'firebase/firestore';
import { onMounted, onUnmounted, ref } from 'vue';
const todo = ref(''); // 輸入框的值
const create = async () => {
  if (!todo.value) { // 確認有輸入值,若為空白則不執行
    return;
  }
  try {
    const docRef = await addDoc(collection(db, 'todoList'), {
    <!-- 裡面放入要新增的資料 -->
      text: todo.value,
      date: new Date().getTime(),
      status: false
    });
    console.log('Document written with ID: ', docRef.id); // 送出後會再回傳一個id值
  } catch (e) {
    console.error('Error adding document: ', e);
  } finally {
    todo.value = '';
  }
};
接著可以到資料庫看一下新增的狀況
查詢資料是用 query()方法
詳細可看官方文件:Perform simple and compound queries in Cloud Firestore
orderBy():與SQL語法中的order by相同,可將資料依指定欄位排序。
DESC 表示結果是由大至小排列
取得資料有兩種方法,getDocs()一次性取得、onSnapshot()取得即時更新,以下範例為使用onSnapshot()方法。
⬇︎⬇︎⬇︎ 我們要將建立的資料取出來,放到todoList裡面,並且即時更新資料(每次新增就要更新資料)
要將資料組成
{
	id:"...",
	text:"...",
	date:"...",
	status:"..."
}
const todoList = ref([]);
let unsubscribe;
onMounted(async () => { //組件掛載完成時
  const lastestQuery = query(collection(db, 'todoList'),orderBy('date', 'desc')); //時間從大到小
  unsubscribe = onSnapshot(lastestQuery, snapshot => { //監聽即時資料更新
    todoList.value = snapshot.docs.map(doc => {
      return {
        id: doc.id,
        ...doc.data()
      };
    });
  });
  
});
onUnmounted(() => { //組件被銷毀時
  if (unsubscribe) {
    unsubscribe(); // 停止監聽資料
  }
});
修改資料可以用setDoc()或updateDoc(),以下範例為使用updateDoc()方法(更新文檔的某些欄位而不覆寫整個文檔)
const update = async todoItem => {
  try {
    await updateDoc(doc(db, 'todoList', todoItem.id), {
      text: todoItem.text,
      status: todoItem.status
    });
  } catch (err) {
    console.error('Error: ', err);
  }
};
刪除資料有兩種方法,updateDoc()刪除欄位、deleteDoc()刪除文件,若要刪除集合,官方不建議
詳細可看官方文件:Delete data from Cloud Firestore
這是刪除某個集合的document文件deleteDoc(doc(db, "collection 的名稱", "document 的名稱"))
這是刪除某個集合的document文件中的欄位
updateDoc(doc(db, 'collection 的名稱', 'document 的名稱'), {
  要刪除的欄位名稱: deleteField()
});
以下範例因為要刪除文件為使用deleteDoc()方法。
const remove = async id => {
  try {
    await deleteDoc(doc(db, 'todoList', id));
  } catch (err) {
    console.error('Error: ', err);
  }
};
這樣就完成拉!
別忘了!使用這些以上方法都須引入喔!
本次範例總共引入以下:
import {collection,addDoc,onSnapshot,orderBy,query,updateDoc,doc,deleteDoc} from 'firebase/firestore';
參考資料:
Firebase Cloud Firestore V9 常用功能筆記
create , fetch , edit , delete (CRUD) Vue.js and Firebase Firestore database
那我們明天再見了~