EP03 | Firebase 中的資料庫 - 獲取 Cloud Firestore 資料庫
如何獲取數據
Firestore 文件提及:
有兩種方法可以檢索存儲在 Cloud Firestore 中的數據。這些方法中的任何一種都可以用於文檔、文檔集合或取得查詢結果:
- 調用一個方法來獲取數據 (
get()
)。- 設置偵聽器以接收數據更改事件 (
onSnapshot()
)。
設置偵聽器時,Cloud Firestore 會向您的偵聽器發送數據的初始快照,然後在每次文檔更改時發送另一個快照。
必須注意到使用 get()
單純只是取得資料庫資料,並不具有獲取實時更新的效果,所以在添加資料或更新資料過後要再調用 get()
才可取得最新資料,而偵聽器 (onSnapshot()
) 只需設置 1 次即可獲取實時更新。
這一篇文章主要紀錄 Firestore 中偵聽器 (onSnapshot()
) 的學習。
使用偵聽器
偵聽文檔
1 | const todoCollection = db.doc('/todos/JUN/todo/HnJNwCjH2Wv7qELj9nRO'); |
偵聽集合
1 | const todoCollection = db.collection('todos').doc('JUN').collection('todo'); |
Snapshot 屬性及方法:
exists
: 文檔是否存在,存在即為true
。id
: 文檔 ID 。metadata
: 資料的狀態。fromCache
: 資料來源,true
代表來自 Cache ,false
代表來自 Server 。hasPendingWrites
: 是否還有尚未寫入到後端的本地資料,true
代表有資料在本地端尚未寫入後端 ,false
代表來自資料已經被寫入後端。(偵聽器將在數據發送到後端之前收到新數據通知。)
data()
: 取得數據。(偵聽文檔)docs
: 取得文檔陣列。(偵聽集合)
有關於 SnapshotListenOptions (
includeMetadataChanges
) ,設定為true
,可以幫助我們除了資料的更改時會收到 snapshot 外,在metadata
有變化的時候也會收到 snapshot 。
偵聽查詢文檔
資料使用 Firestore 提供範例。
1 | const citiesRef = db.collection("cities"); |
建立查詢對象:
利用
db.collection(集合名).where(給定屬性, 比較運算符, 給定值)
來建立查詢對象。Firestore 的比較運算符有下列幾種:
<
: 小於。<=
: 小於或等於。==
: 等於。>
: 大於。>=
: 大於或等於。!=
: 不等於。in
: 返回與給定值(可為多個)其中之一匹配的文檔,使用 == 及邏輯 OR 。
取得或偵聽查詢結果
透過
get()
或onSnapshot()
來取得或偵聽查詢結果。1
2
3
4
5
6//country 是字串
db.collection('cities').where('country', 'in', ['USA', 'Japan']).get().then((query)=>
{
console.log(query.docs)
// DC、LA、SF、TOK
})not-in
: 返回與給定值(可為多個)皆不匹配(且不為null)的文檔,使用 != 及 邏輯 AND 。1
2
3
4
5
6//country 是字串
db.collection('cities').where('country', 'not-in', ['USA', 'Japan']).get().then((query)=>
{
console.log(query.docs)
// BJ
})
(對陣列)
array-contains
: 陣列根據給定值進行過濾。1
2
3
4
5
6
7// regions 是陣列
db.collection('cities').where('regions', 'array-contains',
'west_coast').get().then((query)=>
{
console.log(query.docs)
// SF、LA
})array-contains-any
: 陣列根據給定值(可為多個)進行過濾,返回符合給定值其中一個所有文檔。1
2
3
4
5
6
7
8// regions 是陣列
db.collection('cities').where('regions', 'array-contains-any',
['west_coast', 'east_coast']).get().then((query)=>
{
console.log(query.docs)
// SF、LA、DC
})
指定數據的排序及限制數量
使用 orderBy()
指定數據的排序順序。
1 | // 以城市的人口數作為排序少→多(升冪) |
使用 limit()
限制檢索的文檔數量。
1 | // 結合 limit 限制得到的資料筆數 |
使用查詢游標對數據進行分頁
查詢游標定義查詢的起點和終點,允許您:
- 返回數據的子集。
- 分頁查詢結果。
然而,定義一個特定範圍的查詢時,你應該使用
where()
中描述的方法簡單查詢。
簡單說明一下,查詢的起點跟終點分別使用以下幾種方法:
startAt(‘指定起點’) :包括指定起點。
startAfter(‘指定起點’) :不包括指定起點。
endAt(‘指定終點’) :包括指定終點。
endBefore(‘指定終點’) :不包括指定終點。
1 | // 必須先定義一個查詢範圍,並且以人口數排列 |
使用文檔快照定義查詢游標
將文檔快照中的值用作查詢游標中的起點或終點。
1 | db.collection('cities').doc('TOK').get().then((doc)=>{ |
分頁查詢
查詢游標結合 limit()
做分頁。
1 | let allDataLen = 0 |
參考資料
Get realtime updates with Cloud Firestore