EP02 | Firebase 中的資料庫 - 如何在 Cloud Firestore 中新增、刪除資料
本篇文章主要是來紀錄如何使用、更新及添加文檔,會做一個 TodoList 來說明。
使用 Firestore 的前提
上一篇文章有提到如何在 Firebase 創建 Firestore 資料庫,但仔細觀察一下 Firestore 文件說明中,針對初始化 Firestore 的寫法:
1 | <script src="https://www.gstatic.com/firebasejs/8.6.8/firebase-app.js"></script> |
但在我們得到的 SDK 中是這樣的:
1 | <!-- The core Firebase JS SDK is always required and must be listed first --> |
對比之後會發現,除了要在自己加入 Firestore 的 Library 之外,還必須使用 var db = firebase.firestore();
將 Firestore 初始化。
設置文檔
自訂文檔ID
如果想要在本地專案裡直接創建文檔,並且**自訂文檔名(ID)**的話,可以使用 set()
,接下來來說說 set()
的使用方法:
1 | // 指定集合 todos 中的 JUN 文檔 |
在 TodoList 中新增一筆資料,並且該筆資料送出後,會被儲存在 Firestore 裡。
自動生成文檔名(ID)
set()
在 doc()
中部寫入任何參數,即為隨機生成文檔 ID。
1 | // 不指定文檔名,firestore會自動升成一組隨機的 ID 作為文檔名 |
add()
等同於使用 doc().set(...)
,但更簡潔。
1 | db.collection('todos').add({undo: ['date with parents']}) |
更新文檔
如果只想更改文檔中某一項屬性值的話,要怎麼辦呢?
用 set()
可以嗎?
經過測試的確可以,但有一個前提是一定要加入 {merge: true}
這個參數,否則是覆蓋文檔原本的資料。
1 | const todosCollection = db.collection('todos').doc('JUN'); |
有沒有更簡潔的寫法?
有,就是使用 update()
。
1 | const todosCollection = db.collection('todos').doc('JUN'); |
上面 2 種方法結果都是相同的。
這時候又有一個疑問了,那就是要如何新增陣列值,這時候就要來了解一下 firebase. firestore. FieldValue
這個構造函數了,在 firebase. firestore. FieldValue
包含了幾種方法,除了新增、移除陣列值外,還可以追蹤伺服器何時收到更新以及在資料庫的數值中新增或減少指定數值。
isEqual(val):資料庫的該屬性資料與指定 val 是否相同。
arrayUnion(val):從資料庫的該陣列值中新增指定 val,但只添加不存在的 val 。
1
2
3
4
5
6
7
8
9
10
11todosCollection.undate({
undo: firebase.firestore.FieldValue.arrayUnion('writting')
})
.then(()=>{
// 寫入成功
console.log("Document successfully update!")
})
.catch(err=>{
// 寫入失敗
console.log(err)
})arrayRemove(val):從資料庫的該陣列值中刪除指定 val 。
1
2
3
4
5
6
7
8
9
10
11todosCollection.undate({
undo: firebase.firestore.FieldValue.arrayRemove('reading')
})
.then(()=>{
// 寫入成功
console.log("Document successfully written!")
})
.catch(err=>{
// 寫入失敗
console.log(err)
})increment(number):對資料庫的當前數值進行新增或減少指定 number 。
1
2
3
4
5
6
7
8
9
10
11
12todosCollection.undate({
undo: firebase.firestore.FieldValue.arrayRemove('saving'),
undoNum: firebase.firestore.FieldValue.increment(1)
})
.then(()=>{
// 寫入成功
console.log("Document successfully written!")
})
.catch(err=>{
// 寫入失敗
console.log(err)
})serverTimestamp():跟踪服務器何時收到更新。
1
2
3
4
5
6
7
8
9
10
11
12
13todosCollection.undate({
undo: firebase.firestore.FieldValue.arrayRemove('drinking'),
undoNum: firebase.firestore.FieldValue.increment(1),
updateTime: firebase.firestore.FieldValue.serverTimestamp()
})
.then(()=>{
// 寫入成功
console.log("Document successfully written!")
})
.catch(err=>{
// 寫入失敗
console.log(err)
})
除陣列更新外,要如何指定物件中某項值的更新,這時可以直接使用點表示法來引用文檔中的嵌套字段,並賦予新值。
1 | todosCollection.undate({ |
特別提醒:指定物件屬性名時,一定要使用字串型式。
刪除文檔或文檔中指定屬性
不論是刪除文檔或文檔中指定屬性都是使用 delete()
,只是使用的方法即位置不一樣。
刪除文檔中指定屬性
在文檔使用 update()
,在欲刪除的屬性上使用 firebase.firestore.FieldValue.delete()
。
1 | db.collection('todos').doc('JUN').update({ |
刪除文檔
在文檔使用 delete()
即可直接刪除文檔。
1 | db.collection('todos').doc('JUN').delete() |
參考資料