學習Firebase Firestore(Admin SDK語法)

前言

  • 繼上一篇v9語法,實戰我比較少會使用,接下來紀錄一下較常用的Admin SDK方式操作資料庫!
  • 此為Admin SDK(同前端v8語法),這篇著重在Admin SDK firestore(後端)語法介紹,一般也建議在後端與資料庫溝通,安全性比較足夠。

留意:

  • 須先至 專案設定>>服務帳戶,選擇Node.js,並按下產生新的私密金鑰,再按下產生金鑰,下載json檔案(將其命名為serviceAccountKey.json)存放到專案內

  • 初始化資料庫,並取得db物件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    import { initializeApp, cert } from "firebase-admin/app";
    import { getFirestore } from "firebase-admin/firestore";
    import serviceAccount from "./serviceAccountKey.json";

    initializeApp({
    credential: cert(serviceAccount),
    });

    const db = getFirestore();
  • 接下來以CRUD順序介紹

    • C-(Create)
    • R-(Read)
    • U-(Update)
    • D-(Delete)

C-(Create)創建資料

  • 創建文件(使用set,可命名文件名)
    語法
    1
    await db.collection('集合名').doc('文件名').set(物件資料)
    如果文件不存在則創建,若存在則整個物件覆蓋;若不想整個物件覆蓋,只要修改則要加上參數物件{ merge: true }
    語法
    1
    await db.collection('集合名').doc('文件名').set(物件資料, { merge: true });
    範例
    1
    2
    3
    4
    5
    6
    7
    (async () => {
    await db.collection('cities').doc('LA').set({
    name: 'Los Angeles',
    state: 'CA',
    country: 'USA'
    }, { merge: true });
    })();
  • 創建文件(使用add,Firebase自動命名文件名)
    語法
    1
    await db.collection('集合名').add(物件資料);
    範例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    (async () => {
    const res = await db.collection('cities').add({
    name: 'Tokyo',
    country: 'Japan'
    });

    console.log('創建文件的id: ', res.id);
    })();

    可以取得創建文件的id

R-(Read)查詢資料

  • 查詢文件
    語法

    1
    await db.collection('集合名').doc('文件名').get();

    範例

    1
    2
    3
    4
    5
    6
    7
    8
    (async () => {
    const doc = await db.collection('cities').doc('SF').get();
    if (doc.exists) {
    console.log('文件資料', doc.data());
    } else {
    console.log('查無文件');
    }
    })();

    可以使用.data(),取得資料

  • 從集合查詢多個文件
    語法

    1
    2
    const citiesRef = db.collection('集合名');
    const snapshot = await citiesRef.get();

    如果有條件,加在.get()前面,例如變成const snapshot = await citiesRef.where('欄位名', '==', true).get();
    範例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    (async () => {
    const citiesRef = db.collection('cities');
    const snapshot = await citiesRef.where('capital', '==', true).get();
    if (snapshot.empty) {
    console.log('No matching documents.');
    return;
    }

    snapshot.forEach(doc => {
    console.log(doc.id, '=>', doc.data());
    });
    })();

    使用for…of或是傳統for,必須針對snapshot再加上.docs跑迴圏(如使用forEach則直接使用snapshot)。最後再使用.data(),取得資料。
    例如

    1
    2
    3
    for (const doc of snapshot.docs) {
    console.log(doc.id, '=>', doc.data());
    }

U-(Update)更新資料

  • 更新文件(使用update,非整個物件覆蓋)
    語法

    1
    await db.collection('集合名').doc('文件名').update(物件資料);

    範例

    1
    2
    3
    4
    5
    6
    7
    (async () => {
    await db.collection('cities').doc('LA').update({
    name: "Los Angeles",
    state: "CA",
    country: "new country!",
    })
    })();
  • 更新文件(使用set,替換全部文件內容)
    語法

    1
    await db.collection('集合名').doc('文件名').set(物件資料);

    若不全部替換,務必加上, { merge: true }
    語法

    1
    await db.collection('集合名').doc('文件名').set(物件資料, { merge: true });

    範例
    同本文創建文件set方法

    *小提醒:使用update等同於set加上{ merge: true },效果完全相同

D-(Delete)刪除文件

語法

1
await db.collection('集合名').doc('文件名').delete();

範例

1
2
3
(async () => {
const res = await db.collection('cities').doc('DC').delete();
})();

小結

透過紀錄語法,讓以後的自己方便查找資訊,常常會透過後端與資料庫溝通的方式,取得資料之後再傳遞給前端,這樣作法相比上一篇v9作法更安全!

參考資料
Firebase官方文件