正在儲存資料

儲存資料的方式

PUT 將資料寫入或取代至定義的路徑,例如 fireblog/users/user1/<data>
PATCH 更新已定義路徑的部分鍵,而不替換所有資料。
POST 新增至 Firebase 資料庫中的資料清單。每當我們傳送 POST 要求時,Firebase 用戶端都會產生專屬金鑰,例如 fireblog/users/<unique-id>/<data>
刪除 從指定的 Firebase 資料庫參考資料中移除資料。

使用 PUT 寫入資料

透過 REST API 進行的基本寫入作業為 PUT。目的地: 示範儲存資料,我們將建構內含貼文和使用者的網誌應用程式。所有的 應用程式的資料會儲存在 Firebase 資料庫網址的「fireblog」路徑下 「https://docs-examples.firebaseio.com/fireblog」。

讓我們先將部分使用者資料儲存到 Firebase 資料庫。每個使用者 使用者名稱,我們也會儲存對方的全名和出生日期。每位使用者都有 不重複的使用者名稱,較適合使用 PUT 而不是 POST,因為 我們已有金鑰,您就不需要建立金鑰。

使用 PUT 就能編寫字串、數字、布林值、陣列或任何 JSON 物件, Firebase 資料庫在這個案例中,我們會傳送 物件給該物件:

curl -X PUT -d '{
  "alanisawesome": {
    "name": "Alan Turing",
    "birthday": "June 23, 1912"
  }
}' 'https://docs-examples.firebaseio.com/fireblog/users.json'

將 JSON 物件儲存至資料庫時,物件屬性會 可透過巢狀方式自動對應至子地點。如果我們前往 這裡有「Alan Turing」的值,我們也能 將資料直接儲存至 子地點:

curl -X PUT -d '"Alan Turing"' \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome/name.json'
curl -X PUT -d '"June 23, 1912"' \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome/birthday.json'

以上兩個範例—同時編寫和寫入物件的值 與子地點分開,因此系統會將相同的資料儲存到 Firebase 中 資料庫:

{
  "users": {
    "alanisawesome": {
      "date_of_birth": "June 23, 1912",
      "full_name": "Alan Turing"
    }
  }
}

成功的要求會以 200 OK HTTP 狀態碼表示, 回應會包含我們寫入資料庫的資料。第一個範例只會在 在正在觀看資料的用戶端觸發一個事件,第二個範例則會觸發 第二,請務必注意,如果使用者路徑中已有資料 但第二個方法只會修改每個獨立子項目的值 節點,同時讓其他子項保持不變PUT 相當於 set()

使用 PATCH 更新資料

使用 PATCH 要求,我們可以在沒有位置的情況下,更新特定地點的特定子項 覆寫現有資料讓我們使用 PATCH,在使用者資料中加入杜林的暱稱 要求:

curl -X PATCH -d '{
  "nickname": "Alan The Machine"
}' \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'

上述要求會將 nickname 寫入 alanisawesome 物件 而無需刪除 namebirthday 子項。請注意 而是透過「name」和「birthday」發出PUT要求 已遭刪除,因為這些檔案未包含在要求中。Firebase 中的資料 資料庫就會如下所示:

{
  "users": {
    "alanisawesome": {
      "date_of_birth": "June 23, 1912",
      "full_name": "Alan Turing",
      "nickname": "Alan The Machine"
    }
  }
}

成功的要求會以 200 OK HTTP 狀態碼表示, 回應會包含寫入資料庫的更新資料。

Firebase 也支援多路徑更新。也就是說,PATCH 可同時更新 Firebase 資料庫中多個位置的值,帶來強大的功能 將資料去標準化。透過多路徑更新功能,我們可以同時為 Alan 和 Grace 加上暱稱:

curl -X PATCH -d '{
  "alanisawesome/nickname": "Alan The Machine",
  "gracehopper/nickname": "Amazing Grace"
}' \
  'https://docs-examples.firebaseio.com/fireblog/users.json'

本次更新後,小艾和小蕾也新增了暱稱:

{
  "users": {
    "alanisawesome": {
      "date_of_birth": "June 23, 1912",
      "full_name": "Alan Turing",
      "nickname": "Alan The Machine"
    },
    "gracehop": {
      "date_of_birth": "December 9, 1906",
      "full_name": "Grace Hopper",
      "nickname": "Amazing Grace"
    }
  }
}

請注意,若嘗試透過包含的路徑編寫物件來更新物件,則會造成不同的行為。讓我們看看如果改以這種方式更新 Grace 和 Alan,會發生什麼情況:

curl -X PATCH -d '{
  "alanisawesome": {"nickname": "Alan The Machine"},
  "gracehopper": {"nickname": "Amazing Grace"}
}' \
  'https://docs-examples.firebaseio.com/fireblog/users.json'

這會產生不同的行為,也就是覆寫整個 /fireblog/users 節點:

{
  "users": {
    "alanisawesome": {
      "nickname": "Alan The Machine"
    },
    "gracehop": {
      "nickname": "Amazing Grace"
    }
  }
}

使用條件式要求更新資料

您可以使用條件式要求 (相當於交易的 REST) 進行更新 以便根據其現有狀態的資料適用對象 例如,如果您想要增加支持票數,且想確保 計數正確反映多位同時認同的投票數,請使用條件式 要求將新值寫入計數器。而非兩次寫入 ,因此其中一個寫入要求會失敗, 然後,您可以使用新的值重新提出要求。
  1. 如要在特定位置執行條件式要求,請取得專屬 ID 該位置目前的資料或使用 ETag如果 ETag 也會跟著改變您可以使用任何 PATCH 以外的方法。以下範例使用 GET 要求。
    curl -i 'https://test.example.com/posts/12345/upvotes.json' -H 'X-Firebase-ETag: true'
    
    敬上 具體來說,呼叫標頭中的 ETag 會傳回 指定位置。
    HTTP/1.1 200 OK
    Content-Length: 6
    Content-Type: application/json; charset=utf-8
    Access-Control-Allow-Origin: *
    ETag: [ETAG_VALUE]
    Cache-Control: no-cache
    
    10 // Current value of the data at the specified location
    
  2. 在下一個 PUTDELETE 中加入傳回的 ETag 要求更新 與該 ETag 值完全相符的資料。按照範例 將計數器更新為 11,或大於初始擷取值的 10 並在值不再符合時使要求失敗,請使用以下程式碼:
    curl -iX PUT -d '11' 'https://[PROJECT_ID].firebaseio.com/posts/12345/upvotes.json' -H 'if-match:[ETAG_VALUE]'
    
    敬上 如果指定位置的資料值仍為 10,則 PUT 要求相符,且要求成功,將 11 寫入資料庫。
    HTTP/1.1 200 OK
    Content-Length: 6
    Content-Type: application/json; charset=utf-8
    Access-Control-Allow-Origin: *
    Cache-Control: no-cache
    
    11 // New value of the data at the specified location, written by the conditional request
    
    敬上 如果位置不再與 ETag 不符 (其他使用者可能會發生這種情況) 寫入資料庫的新值;如果未寫入 或 HTTP/HTTPS 位置傳回回應會包含新值和 ETag。
    HTTP/1.1 412 Precondition Failed
    Content-Length: 6
    Content-Type: application/json; charset=utf-8
    Access-Control-Allow-Origin: *
    ETag: [ETAG_VALUE]
    Cache-Control: no-cache
    
    12 // New value of the data at the specified location
    
  3. 如果您決定重試要求,請使用新的資訊。Realtime Database 不會自動重試失敗的條件式要求。不過 也可以使用新的值和 ETag 建構條件式要求,並加入 失敗回應傳回的資訊

以 REST 為基礎的條件式要求會實作 HTTP 如果相符 標準。不過,這些 API 與標準的存在差異如下:

  • 每個比對要求只能提供一個 ETag 值,不能有多個。
  • 雖然標準建議能與所有請求一併傳回 ETag, 即時資料庫只會傳回內含以下要求的 ETag: X-Firebase-ETag 標頭。可降低標準要求的帳單費用。

此外,條件式要求也可能比一般 REST 要求慢。

正在儲存資料清單

為加入 Firebase 資料庫參考資料的每個子項產生一組以時間戳記為準的不重複鍵 我們可以傳送 POST 要求對於 users 路徑,最好 每個使用者都有專屬使用者名稱,因此需要定義自己的金鑰但是,當使用者將網誌文章新增到 應用程式,我們會使用 POST 要求自動產生每篇網誌文章的金鑰:

curl -X POST -d '{
  "author": "alanisawesome",
  "title": "The Turing Machine"
}' 'https://docs-examples.firebaseio.com/fireblog/posts.json'

我們的 posts 路徑現在具備下列資料:

{
  "posts": {
    "-JSOpn9ZC54A4P4RoqVa": {
      "author": "alanisawesome",
      "title": "The Turing Machine"
    }
  }
}

請注意,-JSOpn9ZC54A4P4RoqVa 索引鍵是由系統自動產生,因為 我們使用了 POST 要求要求成功後,將由 200 OK 表示 HTTP 狀態碼,回應會包含新增資料的鍵:

{"name":"-JSOpn9ZC54A4P4RoqVa"}
敬上

移除資料

如要移除資料庫中的資料,我們可以傳送 DELETE 要求,並加上 要刪除資料的路徑網址。以下指令會從我們的 users 路徑:

curl -X DELETE \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'

200 OK HTTP 狀態碼會表示成功的 DELETE 要求,回應中會包含 JSON null

URI 參數

將資料寫入資料庫時,REST API 會接受下列 URI 參數:

auth

auth 要求參數可讓您存取受以下保護的資料: Firebase Realtime Database Security Rules,且為 可支援所有請求類型引數可以是 Firebase 應用程式密鑰,也可以是 驗證權杖,我們會在使用者授權 專區。在下列範例中,我們會傳送 POST 要求,以及 auth 參數,其中 CREDENTIAL 是 Firebase 應用程式密鑰或 驗證權杖:

curl -X POST -d '{"Authenticated POST request"}' \
  'https://docs-examples.firebaseio.com/auth-example.json?auth=CREDENTIAL'
敬上

列印

print 參數可讓我們指定回應的 資料庫將 print=pretty 新增至要求中,會傳回 人類可讀的格式GET 支援 print=prettyPUTPOSTPATCHDELETE 要求。

如要在寫入資料時隱藏伺服器輸出內容,可以將 print=silent。產生的回應會是空白的 如果要求成功,則為 204 No Content HTTP 狀態碼。 print=silent 受到 GETPUTPOSTPATCH 要求。

寫入伺服器值

您可以使用預留位置值將伺服器值寫入某個位置,該預留位置值 只使用一個 ".sv" 金鑰。該鍵的值是我們要設定的伺服器值類型。 舉例來說,如要設定建立使用者時的時間戳記,可用下列操作:

curl -X PUT -d '{".sv": "timestamp"}' \
  'https://docs-examples.firebaseio.com/alanisawesome/createdAt.json'

"timestamp" 是唯一支援的伺服器值,也是自 UNIX 以來的時間 以毫秒為單位進行訓練

提升寫入效能

如果要將大量資料寫入資料庫,可以使用 print=silent 參數,用於改善寫入效能並降低頻寬 。在一般寫入行為中,伺服器會傳回寫入的 JSON 資料。 如果指定 print=silent,伺服器會立即生效 收到資料後關閉連線,降低頻寬用量。

如果我們對資料庫提出多次要求,可重複使用 HTTPS 透過 HTTP 標頭傳送 Keep-Alive 要求,藉此取得連線。

錯誤狀況

在下列情況中,REST API 會傳回錯誤代碼:

HTTP 狀態碼
400 錯誤的要求

下列其中一項錯誤狀況:

  • 無法剖析 PUTPOST 資料。
  • 缺少 PUTPOST 資料。
  • 該要求會嘗試嘗試 PUTPOST 的資料, 太大。
  • REST API 呼叫路徑包含無效的子項名稱。
  • REST API 呼叫路徑過長。
  • 要求含有無法辨識的伺服器值。
  • 查詢中並未定義查詢的索引。 Firebase Realtime Database Security Rules
  • 請求不支援指定的其中一個查詢參數。
  • 這項要求會混合查詢參數和淺層 GET 要求。
401 未授權

下列其中一項錯誤狀況:

找不到 404 找不到指定的 Firebase 資料庫。
500 內部伺服器錯誤 伺服器傳回錯誤。詳情請參閱錯誤訊息。
503 無法使用服務 指定的 Firebase 即時資料庫暫時無法使用,因此 要求。

保護資料

Firebase 的安全性語言可讓我們定義哪些使用者俱有讀取和寫入權限 不同的資料節點詳情請參閱 Realtime Database Security Rules

我們已經介紹如何儲存資料,接著就能學習如何從 Firebase 中擷取資料 透過 REST API 存取資料庫