iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 28
0
Modern Web

從0.5開始的JavaScript系列 第 28

Day28 前端福音(3/4): Firebase-讀取資料

我們已經完成 CRUD 中的 CUD 了,現在就只差臨門一腳。

今日要來講講如何使用 JS 取得 Firebase DB 中的資料!

讀取

主要使用兩個方法:

  1. on
  2. once

第一個 on 會即時更新,也就是只要資料庫一變動,就會抓取到最新資料。

第二個 once 顧名思義只會取得一次,也就是執行時會從資料庫取得最新資料,但往後的更新將不會連動到 client 端的資料,除非再執行一次。

兩者有沒優劣之分,純粹是使用情境不同,像是留言板就能夠使用 on 來讓畫面即時顯示最新的留言。而比較不常變動且數量較多的資料,則可使用 once

雖然 on 很方便,但免費額度的限制下,同時間只允許 100 個連線源。

once

那就先來介紹 once 吧。

我們一樣舉昨天 Bob 國文成績的例子

題外話,我的國文成績一直都不是很好,上課老師開始講課文就睡著Q_Q

如果我們想要取得 Bob 的所有成績,就可以這樣寫:

db.ref("chinese/Bob").once('value', function (snapshot) {
    var data = snapshot.val();
    console.log(data);
});

=> 路徑為 chinese/Bob

=> 然後使用 once 取得最新的資料,

=> 再來是 callback function 中,會有一個參數用來接收從資料庫取出的值,大多習慣會命名為 snapshot

=> 要取得裡面的值可以使用 val() 方法。

所以印出來會長這樣:

都會了嗎,那這邊出個例題,如果我只想要單純取得 Bob 第三次的成績呢?

想好了嗎?

答案是
Ans:

db.ref("chinese/Bob/grade3").once('value', function (snapshot) {
    var data = snapshot.val();
    console.log(data);
});

只需要再指定往下一層路徑就好~

But

因為這是非同步事件,所以想要對取得的資料進行後續操作時,記得寫在 callback function 中。

像是這樣:

db.ref("chinese/Bob").once('value', function (snapshot) {
    renderUI(snapshot.val());
});

不然你會發現怎麼畫面都渲染不出來XD

不了解的可以回去看看 Day5

on

講完 once 的用法後,接下來講講這個即時更新資料的方法吧。

on 的用法和 once 幾乎一樣,把 once 改成 on 而已。

db.ref("chinese/Bob").on('value', function (snapshot) {
    console.log(snapshot.val());
});

它的運作流程是:

  1. 首次取得資料
  2. 在背景待命
  3. 資料庫有資料更動時,把資料撈回
  4. 執行 callback function

不用擔心 on 的即時更新,會導致 callback function 不斷執行。

所以範例中首次取得資料後,只要資料庫沒有資料更動,就不會一直印出 Bob 的所有成績。

on 即時更新範例

上面舉了留言板作為 on 的使用情境,那這邊就使用 on 來實現

線上多人即時更新的 ToDoList」吧!

此範例使用六角學院前陣子舉辦的 The F2E - 前端修練精神時光屋Week1 設計稿。

PS. 只有設計稿而已,還是要自己切版、寫 JS

接下來不會說明該專案的其他技術細節,只會著重在 Firebase on 的使用方法。

成品請點我

都玩過了嗎,也可以多開瀏覽器或使用手機來看看即時更新的效果~

But

有兩點需要注意:

  1. 目前沒有寫上傳檔案的功能,不過不影響本篇的重點。
  2. 該資料庫開放存取規則,請在正常範圍內使用它。

接下來要看的重點其實也只有這個XD

這個專案透過 on 來取得最新的資料,然後把資料存起來後再執行過濾與渲染的動作。

更多操作

講完了如何取得資料後,已經可以應用於大多數狀況,但還是有一些方法來解決特定的情境。

有學過 SQL 指令的都知道,我除了單純的 select 以外,還可以使用 order bylimit...等指令。

Firebase DB 中也有這些方法喔,我們就來看看如何使用吧。

Let's go!

排序

我們在撈出資料時,其實可以多加 orderBy 這個方法來對取出的資料做排序。

常見的有這 3 種:

  1. orderByChild(): 針對特定子節點做排序,參數帶入想要排序的欄位就好。
  2. orderByKey(): 不用帶入參數,依據資料的 key 來做排序。
  3. orderByValue(): 不用帶入參數,依據路徑下的值來做排序。

orderByValue

一樣舉回 Bob 的例子,目前資料庫長這樣:

假設我們想要取出他的成績,並且按照成績由低到高排序,那麼就可以這樣寫:

db.ref("chinese/Bob").orderByValue().once('value', function (snapshot) {
    snapshot.forEach(function (item) {
        console.log(item.key + " " + item.val());
    })
});

PS. orderBy 撈到的資料記得用 forEach 取出

此時取出的資料就不是 90 > 50 > 70,而是會變這樣:

orderByChild

假設今天狀況比較複雜一點,總共有 3 個人的成績:

若是我想針對每個人的成績做排序,將成績由低到高印出。

那麼可以使用 orderByChild 這樣寫:

db.ref("chinese").orderByChild("grade").once('value', function (snapshot) {
    snapshot.forEach(function (item) {
        console.log(item.key + " " + item.val().grade);
    })
});

此時取出的資料也就由小到大了

限制

講完了排序以後,當然不只這樣,接下來還要介紹兩種方法

  1. 區間限制
  2. 筆數限制

PS. 限制的方法記得接在 orderBy 後面

區間限制

第一個區間限制,我可以使用這 3 種方法指定取出的資料範圍:

  1. startAt
  2. endAt
  3. equalTo

按照字面翻譯,startAt 是大於等於的意思、endAt 是小於等於的意思、equalTo 是等於的意思。

所以當我只想取出「有及格」的成績時,

可以這樣寫:

db.ref("chinese").orderByChild("grade").startAt(60).endAt(100).once('value', function (snapshot) {
    snapshot.forEach(function (item) {
        console.log(item.key + " " + item.val().grade);
    })
});

透過 startAt(60).endAt(100) 過濾,所以就只印出 AliceMay 的成績了。

至於 equalTo 的用法也是一樣,就不再寫範例。

比數限制

講完了區間限制,還剩下最後一個筆數限制

  1. limitToFirst()
  2. limitToLast()

這方法能夠限制取出的資料筆數,又細分為從頭開始的前幾筆最尾端的幾筆

假設我想要取出排序後的第一筆而已,也就是「成績最低的同學」。

那麼就可以這樣寫:

db.ref("chinese").orderByChild("grade").limitToFirst(1).once('value', function (snapshot) {
    snapshot.forEach(function (item) {
        console.log(item.key + " " + item.val().grade);
    })
});

透過 limitToFirst(1) 取得排序後的第一筆資料,也就是最低分的 Bob

反過來說,當我想取出「最高分的同學」時,就可以使用 limitToLast:

db.ref("chinese").orderByChild("grade").limitToLast(1).once('value', function (snapshot) {
    snapshot.forEach(function (item) {
        console.log(item.key + " " + item.val().grade);
    })
});

CRUD 的操作都已經完成,趕快學起來加快自己的開發速度,或是可以寫些小作品分享給別人囉!

下一篇會來介紹權限的部分

我們明天見/images/emoticon/emoticon51.gif


上一篇
Day27 前端福音(2/4): Firebase-寫入&刪除資料
下一篇
Day29 前端福音(4/4): Firebase-帳號系統&資料讀寫規則
系列文
從0.5開始的JavaScript30

尚未有邦友留言

立即登入留言