今天來研究如何一次追蹤一個集合中多個文件的變動、針對不同的變動做出不同的對應、以及如何取消追蹤吧!
若是要追蹤一個集合中的多個文件,可以透過 query 相關方法去篩選文件,最後用 onSnapshot()
取代原本要獲取資料的 get()
,其實這部份就和昨天提到的文件變動追蹤是大同小異的,所以簽署式也是一樣的,差別只在 OnNext()
回呼函式拿到的是 QuerySnapshot
,不是 DocumentSnapshot
。
onSnapshot(optionsOrObserverOrOnNext, observerOrOnNextOrOnError, onError) returns function()
這邊以要追蹤行政區集合中,所屬城市是台中的所有行政區為例:
db.collection('districts').where('city', '==', 'Taichung')
.onSnapshot(querySnapshot => {
let districts = []
querySnapshot.forEach(doc => {
districts.push(doc.data().name)
})
console.log('Current districts in Taichung: ', districts.join(', '))
})
而 QuerySnapshot
有提供一個名為 docChanges()
的方法用來追蹤文件變動,它會回傳由 DocumentChange
物件組成的陣列,我們可以透過其中的 type 屬性來暸解變動的類別是新增、更新、還是移除,透過這些資訊我們就可以針對不同的變動類型做出不同的對應方式。若是 onSnapshot()
方法是第一次執行,那麼變動的類型都會是 added
。
db.collection('districts').where('city', '==', 'Taichung')
.onSnapshot(querySnapshot => {
snapshot.docChanges().forEach(change => {
if (change.type === 'added') {
console.log('New district: ', change.doc.data())
}
if (change.type === 'modified') {
console.log('Modified district: ', change.doc.data())
}
if (change.type === 'removed') {
console.log('Removed district: ', change.doc.data())
}
})
})
最後來講講該如何取消追蹤變動,其實方法很簡單。當我們在呼叫 onSnapshot()
方法時,它會回傳一個函式,該函式就是取消追蹤的函式,所以我們可以在呼叫 onSnapshot()
時,將其回傳的值記錄下來。
let unsubscribe = db.collection('districts')
.where('city', '==', 'Taichung')
.onSnapshot(querySnapshot => { /* ... */ })
// ...
// 停止追蹤變動
unsubscribe()