上一篇,建立了firestore資料庫,並且成功與前端連接,讀取到資料庫的資料,那麼這一篇就來認識一下,什麼是 firestore、firestore可以做什麼。
之前有提到 firestore 是 NoSQL
的資料庫,那什麼是 NoSQL 呢? 和 NoSQL 相對應的就是 SQL ,SQL 最主要是用來查詢關聯式資料庫
關聯式資料庫將不同的資料放在不同的表裡面存放,會建立不同表的關聯,並且使用查詢語法去查詢想要的資料,例如:
SELECT * FROM USERS WHERE age>20;
因此怎麼設計資料庫,資料庫的欄位與結構等等就是一個重要且複雜的工作。
而 NoSQL 強調的就是,不需要去強調不同表之間的關係,也不需要去設計資料庫的欄位。資料皆以 key-value pair
的方式,以 JSON 的格式儲存。也就不用去煩惱怎麼設計資料庫。非常適合對於後端沒有完整概念的前端入門後端的一個方法。
而 firestore 就是一個很棒一窺後端世界的好工具。
在 firestore 雖然不用去設計資料庫的欄位,但是有兩項要認識的是集合(collection)與文件(document)
在 google 官方文件說明,將 collection 比喻為資料夾,而將 document 比喻為資料夾的文件。
也就是像這張圖片一樣,建立一個水果的集合,下面文件就是各個水果。當然水果的內容要記錄什麼也沒有強制規定一定都要一樣。
像是可以紀錄蘋果的價錢、香蕉的產地、橘子的樣貌、西瓜的品種不同的資訊都可以,端看自己的需求與操作,沒有任何強硬的限制。
簡單認識了什麼是firestore之後,接下來用 angular-fire 來對 firestore 做最基本的 CRUD的動作
假設要對於水果這個集合做各種動作,那麼先定義好水果的集合
fruitCollection = this.firestore.collection('fruits');
新增資料,分為三種:
addDataWithoutName(): void {
this.fruitCollection.add({
price: 20,
});
}
addDataWithRandomName(): void {
const id = this.firestore.createId();
this.fruitCollection.doc(id).set({
height: '18cm',
});
// 新增完可以直接拿 id 做下一步其他的操作
}
addDataWithSpecificName(): void {
this.fruitCollection.doc('pineapple').set({
weight: 600,
});
}
以上就是三個不同的方法打到資料庫之後,結果的呈現
add
的方法,帶入資料的內容即可。createId
方法幫你產生id,再去建立內容。這樣的使用情境大多數為文件建立之後,馬上會去做更新的動作會常用到覆蓋
原有的文件updateDoc():void{
this.fruitCollection.doc('pineapple').update({
price:200
})
}
更新資料非常簡單,只要指定文件名稱,使用 update
方法之後,只需要填入要更新的部分,就可以更新文件囉
像原本的的鳳梨只有重量的資訊,現在透過更新的方法加入價格的資訊
deleteDoc(){
this.fruitCollection.doc('pineapple').delete()
}
刪除資料的方法同樣很簡單,只要使用 delete
的方法就好了。
以上的方法angular fire 都包裝成 promise
如果想要進行下一步的動作,使用 then
就可以繼續執行了。
如果想要使用 rxjs 的 observable
的方式進行的話,只要將promise 轉換就好了
addDataWithoutName(): void {
const add = this.fruitCollection.add({
price: 20,
});
// 將 promise 轉換成 observable
from(add).subscribe(() => {
//下一步動作
});
}
angular fire 將讀取資料直接包裝成 observable 的方法,並且還有監聽變動的功能,也就是說只要資料庫有變動,會自動得到最新的資料,不用前端去呼叫檢查更新。這個就是 firestore 強大的地方
fruitList$: Observable<any[]> = this.fruitCollection.valueChanges();
fruitList: any[] = [];
getFruitList(): void {
this.fruitList$.subscribe((fruitList) => (this.fruitList = fruitList));
}