保存資料的方法 | |
---|---|
放 | 將資料寫入或替換到定義的路徑,例如fireblog/users/user1/<data> |
修補 | 更新已定義路徑的一些鍵,而不替換所有資料。 |
郵政 | 新增到我們的 Firebase 資料庫中的資料清單。每次我們發送POST 請求時,Firebase 用戶端都會產生一個唯一的金鑰,例如fireblog/users/<unique-id>/<data> |
刪除 | 從指定的 Firebase 資料庫參考中刪除資料。 |
使用 PUT 寫入數據
透過 REST API 的基本寫入操作是PUT
。為了演示保存數據,我們將建立一個包含帖子和用戶的部落格應用程式。我們應用程式的所有資料將儲存在 Firebase 資料庫 URL「https://docs-examples.firebaseio.com/fireblog」的「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
相當於 JavaScript SDK 中的set()
。
使用 PATCH 更新數據
使用PATCH
請求,我們可以更新某個位置的特定子項,而無需覆蓋現有資料。讓我們透過PATCH
請求將圖靈的暱稱加入他的用戶資料:
curl -X PATCH -d '{ "nickname": "Alan The Machine" }' \ 'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'
上述請求會將nickname
寫入我們的alanisawesome
對象,而不會刪除孩子的name
或birthday
。請注意,如果我們在此處發出PUT
請求,則name
和birthday
將被刪除,因為它們未包含在請求中。我們的 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)來根據資料的現有狀態更新資料。例如,如果您想要增加贊成票計數器,並希望確保計數準確反映多個同時贊成票,請使用條件請求將新值寫入計數器。兩次寫入不會將計數器更改為相同的數字,而是其中一個寫入請求失敗,然後您可以使用新值重試該請求。- 若要在某個位置執行條件請求,請取得該位置目前資料的唯一識別碼或 ETag。如果該位置的資料發生變化,ETag 也會發生變化。您可以使用
PATCH
以外的任何方法請求 ETag。以下範例使用GET
請求。curl -i 'https://test.example.com/posts/12345/upvotes.json' -H 'X-Firebase-ETag: true'
具體呼叫 header 中的 ETag 傳回 HTTP 回應中指定位置的 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
- 將傳回的 ETag 包含在下一個
PUT
或DELETE
請求中,以更新與該 ETag 值專門匹配的資料。按照我們的範例,要將計數器更新為 11,或比初始取得的值 10 大 1,並且如果該值不再匹配,則請求失敗,請使用以下程式碼:curl -iX PUT -d '11' 'https://[PROJECT_ID].firebaseio.com/posts/12345/upvotes.json' -H 'if-match:[ETAG_VALUE]'
如果指定的資料值location仍然是10,PUT
請求中的ETag匹配,請求成功,將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 相符(如果其他使用者向資料庫寫入新值則可能會發生這種情況),則請求將失敗,而不會寫入該位置。回傳響應包括新值和 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
- 如果您決定重試請求,請使用新資訊。即時資料庫不會自動重試失敗的條件請求。但是,您可以使用新值和 ETag 透過失敗回應傳回的資訊來建立新的條件請求。
基於 REST 的條件請求實作 HTTP if-match標準。但是,它們在以下方面與標準不同:
- 您只能為每個 if-match 請求提供一個 ETag 值,而不能提供多個。
- 雖然標準建議所有請求都傳回 ETag,但即時資料庫僅傳回包含
X-Firebase-ETag
標頭的請求的 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" } } }
請注意,由於我們使用了POST
請求,因此會自動為我們產生金鑰-JSOpn9ZC54A4P4RoqVa
。成功的請求將由200 OK
HTTP 狀態代碼指示,並且回應將包含新增的新資料的金鑰:
{"name":"-JSOpn9ZC54A4P4RoqVa"}
刪除數據
要從資料庫中刪除數據,我們可以發送一個DELETE
請求,其中包含要刪除資料的路徑的 URL。以下將從我們的users
路徑中刪除 Alan:
curl -X DELETE \ 'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'
成功的DELETE
請求將由200 OK
HTTP 狀態碼以及包含 JSON null
回應指示。
URI參數
將資料寫入資料庫時,REST API 接受以下 URI 參數:
授權
auth
請求參數允許存取受Firebase 即時資料庫安全規則保護的數據,並且所有請求類型都支援。此參數可以是我們的 Firebase 應用程式金鑰或身份驗證令牌,我們將在使用者授權部分介紹這些內容。在以下範例中,我們傳送帶有auth
參數的POST
請求,其中CREDENTIAL
是我們的 Firebase 應用程式金鑰或驗證令牌:
curl -X POST -d '{"Authenticated POST request"}' \ 'https://docs-examples.firebaseio.com/auth-example.json?auth=CREDENTIAL'
列印
print
參數讓我們指定資料庫回應的格式。在我們的請求中新增print=pretty
將以人類可讀的格式傳回資料。 print=pretty
支援GET
、 PUT
、 POST
、 PATCH
和DELETE
請求。
為了在寫入資料時抑制伺服器的輸出,我們可以在請求中新增print=silent
。如果請求成功,產生的回應將為空,並由204 No Content
HTTP 狀態代碼指示。 print=silent
由GET
、 PUT
、 POST
和PATCH
請求支援。
寫入伺服器值
可以使用佔位符值將伺服器值寫入某個位置,該佔位符值是具有單一".sv"
鍵的物件。該鍵的值是我們希望設定的伺服器值的類型。例如,要在建立使用者時設定時間戳,我們可以執行以下操作:
curl -X PUT -d '{".sv": "timestamp"}' \ 'https://docs-examples.firebaseio.com/alanisawesome/createdAt.json'
"timestamp"
是唯一支援的伺服器值,是自 UNIX 紀元以來的時間(以毫秒為單位)。
提高寫入效能
如果我們要將大量資料寫入資料庫,我們可以使用print=silent
參數來提高寫入效能並減少頻寬使用。在正常的寫入行為中,伺服器會使用寫入的 JSON 資料進行回應。當指定print=silent
時,伺服器一旦收到資料就立即關閉連接,從而減少頻寬使用。
如果我們向資料庫發出許多請求,我們可以透過在 HTTP 標頭中傳送Keep-Alive
請求來重新使用 HTTPS 連線。
錯誤狀況
在以下情況下,REST API 將傳回錯誤代碼:
HTTP 狀態碼 | |
---|---|
400錯誤請求 | 以下錯誤情況之一:
|
401未經授權 | 以下錯誤情況之一:
|
404未找到 | 找不到指定的 Firebase 資料庫。 |
500內部伺服器錯誤 | 伺服器回傳錯誤。請參閱錯誤訊息以獲取更多詳細資訊。 |
503服務不可用 | 指定的 Firebase 即時資料庫暫時不可用,這表示未嘗試請求。 |
保護資料安全
Firebase 有一種安全語言,可讓我們定義哪些使用者對資料的不同節點具有讀寫存取權限。您可以在即時資料庫安全規則中閱讀更多相關資訊。
現在我們已經介紹了保存數據,我們可以在下一節中了解如何透過 REST API 從 Firebase 資料庫檢索數據。