Ways to Save Data | |
|---|---|
| ПОМЕЩАТЬ | Запишите или замените данные по указанному пути , например fireblog/users/user1/<data> |
| ПЛАСТЫРЬ | Обновить некоторые ключи для определенного пути без замены всех данных. |
| ПОЧТА | Добавляет данные в список нашей базы данных Firebase. Каждый раз, когда мы отправляем POST запрос, клиент Firebase генерирует уникальный ключ, например, fireblog/users/<unique-id>/<data> |
| УДАЛИТЬ | Удалить данные из указанной ссылки базы данных Firebase. |
Writing Data with PUT
Базовая операция записи через REST API — PUT . Чтобы продемонстрировать сохранение данных, мы создадим приложение для блога с записями и пользователями. Все данные нашего приложения будут храниться по пути `fireblog`, по URL-адресу базы данных Firebase `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"
}
}
} Успешный запрос будет отмечен кодом статуса HTTP 200 OK , а ответ будет содержать данные, записанные нами в базу данных. Первый пример вызовет только одно событие у клиентов, отслеживающих данные, тогда как второй пример — два. Важно отметить, что если данные уже существовали в пути пользователя, первый подход перезапишет их, а второй метод изменит только значение каждого отдельного дочернего узла, оставив остальные дочерние узлы без изменений. PUT эквивалентен set() в нашем JavaScript SDK.
Updating Data with 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"
}
}
} Успешный запрос будет подтвержден кодом статуса HTTP 200 OK , а ответ будет содержать обновленные данные, записанные в базу данных.
Firebase также поддерживает многопутевые обновления. Это означает, что PATCH теперь может обновлять значения в нескольких местах базы данных Firebase одновременно — мощная функция, которая позволяет денормализовать данные . Используя многопутевые обновления, мы можем одновременно добавлять псевдонимы как для Алана, так и для Грейс:
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"
}
}
}Обратите внимание, что попытка обновить объекты путём записи объектов с указанием путей приведёт к иному результату. Давайте посмотрим, что произойдёт, если мы попытаемся обновить Грейс и Алана следующим образом:
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"
}
}
}Updating Data with Conditional Requests
Вы можете использовать условные запросы, REST-аналог транзакций, для обновления данных в соответствии с их текущим состоянием. Например, если вы хотите увеличить счётчик голосов «за» и убедиться, что он точно отражает несколько одновременных голосов «за», используйте условный запрос для записи нового значения в счётчик. Вместо двух операций записи, изменяющих значение счётчика на одно и то же значение, один из запросов на запись завершится ошибкой, и вы сможете повторить запрос с новым значением.- Чтобы выполнить условный запрос к определённому местоположению, получите уникальный идентификатор текущих данных в этом месте, или ETag. При изменении данных в этом месте изменится и ETag. Вы можете запросить ETag любым методом, кроме
PATCH. В следующем примере используетсяGETзапрос. В частности, вызов ETag в заголовке возвращает ETag указанного местоположения в HTTP-ответе.curl -i 'https://test.example.com/posts/12345/upvotes.json' -H 'X-Firebase-ETag: true'
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, или на 1 больше первоначально полученного значения 10, и отменить запрос, если значение больше не соответствует, используйте следующий код: Если значение данных в указанном месте по-прежнему равно 10, ETag в запросеcurl -iX PUT -d '11' 'https://[PROJECT_ID].firebaseio.com/posts/12345/upvotes.json' -H 'if-match:[ETAG_VALUE]'
PUTсовпадает, и запрос выполняется успешно, записывая 11 в базу данных. Если местоположение больше не соответствует ETag, что может произойти, если другой пользователь записал новое значение в базу данных, запрос завершается ошибкой без записи в местоположение. Возвращаемый ответ включает новое значение и ETag.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
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
- Используйте новую информацию, если решите повторить запрос. Realtime Database не выполняет автоматически повторные условные запросы, которые завершились неудачей. Однако вы можете использовать новое значение и ETag для создания нового условного запроса с информацией, возвращаемой в ответе об ошибке.
Условные запросы на основе REST реализуют стандарт HTTP if-match . Однако они отличаются от стандарта следующим:
- Для каждого запроса if-match можно указать только одно значение ETag, а не несколько.
- Хотя стандарт предполагает возврат ETag со всеми запросами, Realtime Database возвращает ETag только с запросами, содержащими заголовок
X-Firebase-ETag. Это снижает расходы на оплату стандартных запросов.
Условные запросы также могут быть медленнее обычных запросов REST.
Saving Lists of Data
Чтобы сгенерировать уникальный ключ с временной меткой для каждого дочернего элемента, добавленного в ссылку базы данных Firebase, мы можем отправить POST запрос. Для пути наших users имело смысл определить собственные ключи, поскольку у каждого пользователя уникальное имя. Но когда пользователи добавляют записи блога в приложение, мы будем использовать POST запрос для автоматической генерации ключа для каждой записи блога:
curl -X POST -d '{
"author": "alanisawesome",
"title": "The Turing Machine"
}' 'https://docs-examples.firebaseio.com/fireblog/posts.json'
Our posts path now has the following data:
{
"posts": {
"-JSOpn9ZC54A4P4RoqVa": {
"author": "alanisawesome",
"title": "The Turing Machine"
}
}
}Обратите внимание, что ключ -JSOpn9ZC54A4P4RoqVa был автоматически сгенерирован, поскольку мы использовали POST запрос. Успешное выполнение запроса будет подтверждено кодом статуса HTTP 200 OK , а ответ будет содержать ключ новых добавленных данных:
{"name":"-JSOpn9ZC54A4P4RoqVa"}Removing Data
Чтобы удалить данные из базы данных, мы можем отправить запрос DELETE с URL-адресом пути, из которого мы хотим удалить данные. Следующий код удалит Алана из пути users :
curl -X DELETE \ 'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'
Успешный запрос DELETE будет обозначен кодом статуса HTTP 200 OK с ответом, содержащим JSON null .
Параметры URI
REST API принимает следующие параметры URI при записи данных в базу данных:
аутентификация
Параметр запроса 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 к нашему запросу вернет данные в удобном для восприятия формате. print=pretty поддерживается запросами GET , PUT , POST , PATCH и DELETE .
Чтобы подавить вывод данных с сервера, можно добавить к запросу print=silent . Полученный ответ будет пустым и будет отмечен кодом статуса HTTP 204 No Content в случае успешного выполнения запроса. Параметр print=silent поддерживается запросами GET , PUT , POST и PATCH .
Writing Server Values
Значения сервера можно записать в определённое место, используя значение-заполнитель, представляющее собой объект с одним ключом ".sv" . Значение этого ключа — это тип значения сервера, который мы хотим установить. Например, чтобы установить временную метку при создании пользователя, можно сделать следующее:
curl -X PUT -d '{".sv": "timestamp"}' \
'https://docs-examples.firebaseio.com/alanisawesome/createdAt.json'
"timestamp" — единственное поддерживаемое сервером значение, представляющее собой время с начала эпохи UNIX в миллисекундах.
Improving Write Performance
При записи больших объёмов данных в базу данных можно использовать параметр print=silent для повышения производительности записи и снижения нагрузки на полосу пропускания. При обычной записи сервер отвечает записанными JSON-данными. При указании параметра print=silent сервер немедленно закрывает соединение после получения данных, что снижает нагрузку на полосу пропускания.
В случаях, когда мы делаем много запросов к базе данных, мы можем повторно использовать HTTPS-соединение, отправив запрос Keep-Alive в заголовке HTTP.
Ошибочные состояния
REST API будет возвращать коды ошибок при следующих обстоятельствах:
| Коды состояния HTTP | |
|---|---|
| 400 Неверный запрос | One of the following error conditions:
|
| 401 Неавторизованный | One of the following error conditions:
|
| 404 Не найдено | The specified Firebase database was not found. |
| 500 Внутренняя ошибка сервера | Сервер вернул ошибку. Подробности см. в сообщении об ошибке. |
| 503 Служба недоступна | Указанная база данных Firebase Realtime временно недоступна, что означает, что запрос не был выполнен. |
Securing Data
В Firebase есть язык безопасности, позволяющий определять, какие пользователи имеют доступ на чтение и запись к различным узлам наших данных. Подробнее об этом можно узнать в разделе Realtime Database Security Rules .
Теперь, когда мы рассмотрели сохранение данных, в следующем разделе мы можем узнать, как извлечь наши данные из базы данных Firebase через REST API.