Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

保存數據

保存數據的方法

寫或替換數據來定義的路徑,象fireblog/users/user1/<data>
修補在不替換所有數據的情況下更新定義路徑的一些鍵。
郵政加入我們的火力地堡數據庫中的數據的列表。我們發送一個每一次POST請求時,火力地堡客戶端生成一個唯一的密鑰,如fireblog/users/<unique-id>/<data>
刪除從指定的 Firebase 數據庫引用中刪除數據。

使用 PUT 寫入數據

通過REST API的基本寫操作PUT 。為了演示保存數據,我們將構建一個包含帖子和用戶的博客應用程序。我們應用程序的所有數據都將存儲在“fireblog”路徑下,位於 Firebase 數據庫 URL“https://docs-examples.firebaseio.com/fireblog”。

讓我們首先將一些用戶數據保存到我們的 Firebase 數據庫。我們將通過唯一的用戶名存儲每個用戶,我們還將存儲他們的全名和出生日期。由於每個用戶都會有一個唯一的用戶名,是有意義的使用PUT ,而不是在這裡POST ,因為我們已經有鑰匙,並不需要創建一個。

使用PUT ,我們可以寫一個字符串,數字,布爾值,數組或JSON對象到我們的火力地堡數據庫。在這種情況下,我們將傳遞一個對象:

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()在我們的JavaScript SDK。

使用 PATCH 更新數據

使用PATCH的要求,我們可以更新在一個特定的位置,而不兒童覆蓋已有的數據。讓我們添加圖靈的暱稱他與用戶數據PATCH請求:

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

上述要求會寫nickname給我們alanisawesome對象而不刪除namebirthday的孩子。需要注意的是,如果我們已經發出了PUT這裡請求,而不是, namebirthday會被刪除,因為他們不是在請求包括在內。 Firebase 數據庫中的數據現在如下所示:

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

一個成功的請求將通過被指示200 OK HTTP狀態代碼,並且響應將包含寫入到數據庫中的更新的數據。

Firebase 還支持多路徑更新。這意味著, PATCH現在可以在同一時間在你的火力地堡數據庫多個位置更新價值觀,強大的功能,它允許幫助你非規範化數據。使用多路徑更新,我們可以同時為 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)根據數據的現有狀態更新數據。例如,如果您想增加一個 upvote 計數器,並希望確保計數準確反映多個同時的 upvotes,請使用條件請求將新值寫入計數器。與將計數器更改為相同數字的兩次寫入不同,其中一個寫入請求失敗,然後您可以使用新值重試該請求。
  1. 要在某個位置執行條件請求,請獲取該位置當前數據的唯一標識符或 ETag。如果該位置的數據發生變化,ETag 也會發生變化。你可以比其他任何方法請求一個ETag PATCH 。以下示例使用一GET請求。
    curl -i 'https://test.example.com/posts/12345/upvotes.json' -H 'X-Firebase-ETag: true'
    
    具體地調用的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
    
  2. 包括返回的ETag在你的下一個PUTDELETE請求到專門匹配ETag值更新數據。在我們的例子,給計數器更新到11,或1比10的初始獲取的值大,並且請求失敗如果該值不再匹配,使用以下代碼:
    curl -iX PUT -d '11' 'https://[PROJECT_ID].firebaseio.com/posts/12345/upvotes.json' -H 'if-match:[ETAG_VALUE]'
    
    如果數據在指定的值位置仍然如圖10所示,在ETag的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的,如果另一個用戶添加了一個新值到數據庫中可能發生,請求失敗,而無需編寫的位置。返迴響應包括新值和 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. 如果您決定重試請求,請使用新信息。實時數據庫不會自動重試失敗的條件請求。但是,您可以使用新值和 ETag 使用失敗響應返回的信息構建新的條件請求。

基於REST的條件請求執行HTTP如果匹配標準。但是,它們在以下方面與標準不同:

  • 您只能為每個 if-match 請求提供一個 ETag 值,而不是多個。
  • 雖然標準建議的ETag與所有請求被退回,實時數據庫只返回與請求包括ETag的X-Firebase-ETag頭。這降低了標準請求的計費成本。

條件請求也可能比典型的 REST 請求慢。

保存數據列表

要生成添加到火力地堡數據庫參考,我們可以送每個孩子獨特的,基於時間戳的關鍵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與我們想刪除數據的路徑的URL請求。下面就從我們刪除艾倫users路徑:

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

一個成功的DELETE請求將由一個指示200 OK用含有JSON的響應的HTTP狀態代碼null

URI 參數

將數據寫入數據庫時,REST API 接受以下 URI 參數:

授權

auth請求參數允許訪問受保護的數據火力地堡實時數據庫的規則,並且所有請求類型都支持。該參數可以是我們的火力地堡的應用程序秘密或令牌的認證,我們將在覆蓋用戶授權部分。在下面的例子中,我們發送POST與要求auth參數,其中CREDENTIAL要么是我們的火力地堡的應用程序秘密或身份驗證令牌:

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

打印

print參數讓我們指定我們從數據庫響應的格式。添加print=pretty了我們的請求將在人類可讀的格式返回數據。 print=pretty是支持GETPUTPOSTPATCHDELETE請求。

要在寫入數據時,抑制來自服務器的輸出,我們可以添加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連接Keep-Alive的HTTP標頭請求。

錯誤條件

在這些情況下,REST API 將返回錯誤代碼:

HTTP 狀態代碼
400錯誤的請求

以下錯誤條件之一:

  • 無法解析PUTPOST數據。
  • 缺少PUTPOST數據。
  • 請求嘗試PUTPOST太大的數據。
  • REST API 調用包含無效的子名稱作為路徑的一部分。
  • REST API 調用路徑太長。
  • 請求包含無法識別的服務器值。
  • 為查詢索引不是在您定義的火力地堡實時的數據庫規則
  • 該請求不支持指定的查詢參數之一。
  • 請求混合查詢帶著淺淺的參數GET請求。
401未授權

以下錯誤條件之一:

404未找到未找到指定的 Firebase 數據庫。
500內部服務器錯誤服務器返回錯誤。有關更多詳細信息,請參閱錯誤消息。
503服務不可用指定的 Firebase 實時數據庫暫時不可用,這意味著未嘗試請求。

保護數據

Firebase 有一種安全語言,可讓我們定義哪些用戶對我們數據的不同節點具有讀寫訪問權限。你可以閱讀更多關於它實時的數據庫規則

既然我們已經介紹了保存數據,我們可以在下一節中了解如何通過 REST API 從 Firebase 數據庫中檢索我們的數據。