Чтение данных с помощью GET
Мы можем прочитать данные из нашей базы данных Firebase, отправив GET
-запрос на её конечную точку URL. Давайте продолжим наш пример с блогом из предыдущего раздела и прочитаем все данные из записей блога:
curl 'https://docs-examples.firebaseio.com/fireblog/posts.json?print=pretty'
Успешный запрос будет подтвержден кодом статуса HTTP 200 OK
, а ответ будет содержать извлекаемые нами данные.
Добавление параметров URI
REST API принимает несколько параметров запроса при чтении данных из нашей базы данных Firebase. Ниже перечислены наиболее часто используемые параметры. Полный список см. в справочнике REST API .
аутентификация
Параметр запроса auth
позволяет получить доступ к данным, защищённым Firebase Realtime Database Security Rules , и поддерживается всеми типами запросов. Аргументом может быть либо секрет вашего приложения Firebase, либо токен аутентификации, как описано в разделе «Пользователи в проектах Firebase» . В следующем примере мы отправляем GET
запрос с параметром auth
, где CREDENTIAL
— это либо секрет вашего приложения Firebase, либо токен аутентификации:
curl 'https://docs-examples.firebaseio.com/auth-example.json?auth=CREDENTIAL'
печать
Указание print=pretty
возвращает данные в удобочитаемом формате.
curl 'https://docs-examples.firebaseio.com/fireblog/posts.json?print=pretty'
Указание print=silent
возвращает код 204 No Content
в случае успешного выполнения.
curl 'https://docs-examples.firebaseio.com/fireblog/posts.json?print=silent'
перезвонить
Для выполнения REST-вызовов из веб-браузера между доменами можно использовать JSONP для обертывания ответа в функцию обратного вызова JavaScript. Добавьте callback=
, чтобы REST API обернул возвращаемые данные в указанную вами функцию обратного вызова. Например:
<script> function gotData(data) { console.log(data); } </script> <script src="https://docs-examples.firebaseio.com/fireblog/posts.json?callback=gotData">
мелкий
Это расширенная функция, разработанная для работы с большими наборами данных без необходимости скачивать всё. Чтобы использовать её, добавьте параметр shallow=true
. Это ограничит глубину возвращаемых данных. Если данные в локации представляют собой примитив JSON (строку, число или логическое значение), будет просто возвращено их значение. Если снимок данных в локации представляет собой JSON-объект, значения для каждого ключа будут усечены до true . Например, используйте следующие данные:
{ "message": { "user": { "name": "Chris" }, "body": "Hello!" } } // A request to /message.json?shallow=true // would return the following: { "user": true, "body": true } // A request to /message/body.json?shallow=true // would simply return: "Hello!"
Попробуйте сделать это с помощью следующего curl
запроса:
curl 'https://docs-examples.firebaseio.com/rest/retrieving-data.json?shallow=true&print=pretty'
тайм-аут
Используйте это, чтобы ограничить время чтения на стороне сервера. Если запрос на чтение не завершается в течение отведенного времени, он завершается с ошибкой HTTP 400. Это особенно полезно, когда вы ожидаете небольшой объем передачи данных и не хотите слишком долго ждать загрузки потенциально большого поддерева. Фактическое время чтения может варьироваться в зависимости от размера данных и кэширования.
Укажите timeouts
в следующем формате: 3ms
, 3s
или 3min
, с указанием числа и единицы измерения. Если тайм-аут не указан, будет применяться максимальный timeout
15min
. Если timeout
не положительный или превышает максимальный, запрос будет отклонен с ошибкой HTTP 400. В следующем примере запрос GET
включает timeout
10 секунд.
curl 'https://docs-examples.firebaseio.com/rest/retrieving-data.json?timeout=10s'
Фильтрация данных
Мы можем создавать запросы для фильтрации данных по различным факторам. Для начала укажите, как именно должны быть отфильтрованы данные, с помощью параметра orderBy
. Затем вы можете комбинировать orderBy
с любым из пяти других параметров: limitToFirst
, limitToLast
, startAt
, endAt
и equalTo
.
Поскольку все мы в Firebase считаем, что динозавры — это очень круто, мы воспользуемся фрагментом из образца базы данных с фактами о динозаврах, чтобы продемонстрировать, как можно фильтровать данные:
{ "lambeosaurus": { "height": 2.1, "length": 12.5, "weight": 5000 }, "stegosaurus": { "height": 4, "length": 9, "weight": 2500 } }
Фильтрация данных возможна тремя способами: по дочернему ключу , по ключу или по значению . Запрос начинается с одного из этих параметров, а затем должен быть дополнен одним или несколькими из следующих параметров: startAt
, endAt
, limitToFirst
, limitToLast
или equalTo
.
Фильтрация по указанному дочернему ключу
Мы можем фильтровать узлы по общему дочернему ключу, передав этот ключ в параметр orderBy
. Например, чтобы получить всех динозавров ростом больше 3, можно сделать следующее:
curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="height"&startAt=3&print=pretty'
Любой узел, не имеющий дочернего ключа, по которому мы фильтруем, будет отсортирован со значением null
. Подробнее об упорядочивании данных см. в разделе «Как упорядочиваются данные» .
Firebase также поддерживает запросы, упорядоченные по глубоко вложенным дочерним элементам, а не только по элементам, расположенным на один уровень ниже. Это полезно, если у вас есть глубоко вложенные данные, например:
{ "lambeosaurus": { "dimensions": { "height" : 2.1, "length" : 12.5, "weight": 5000 } }, "stegosaurus": { "dimensions": { "height" : 4, "length" : 9, "weight" : 2500 } } }
Теперь для запроса высоты мы используем полный путь к объекту, а не отдельный ключ:
curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="dimensions/height"&startAt=3&print=pretty'
Запросы могут фильтроваться только по одному ключу за раз. Использование параметра orderBy
несколько раз в одном запросе приводит к ошибке.
Фильтрация по ключу
Мы также можем фильтровать узлы по их ключам, используя параметр orderBy="$key"
. Следующий пример извлекает всех динозавров с именами, начинающимися с букв a
до m
:
curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="$key"&startAt="a"&endAt="m"&print=pretty'
Фильтрация по значению
Мы можем фильтровать узлы по значению их дочерних ключей, используя параметр orderBy="$value"
. Предположим, динозавры проводят соревнования по диноспортивному спорту, и мы отслеживаем их результаты в следующем формате:
{ "scores": { "bruhathkayosaurus": 55, "lambeosaurus": 21, "linhenykus": 80, "pterodactyl": 93, "stegosaurus": 5, "triceratops": 22 } }
Чтобы получить всех динозавров с оценкой выше 50, мы можем сделать следующий запрос:
curl 'https://dinosaur-facts.firebaseio.com/scores.json?orderBy="$value"&startAt=50&print=pretty'
См. раздел «Как упорядочиваются данные», где объясняется, как сортируются значения null
, boolean, string и object при использовании orderBy="$value"
.
Сложная фильтрация
Мы можем комбинировать несколько параметров для построения более сложных запросов.
Ограничить запросы
Параметры limitToFirst
и limitToLast
используются для задания максимального количества дочерних элементов, для которых требуется получить данные. Если установить ограничение в 100, мы получим не более 100 соответствующих дочерних элементов. Если в базе данных хранится менее 100 сообщений, мы получим данные по каждому дочернему элементу. Однако, если сообщений больше 100, мы получим данные только по 100 из них. Это будут первые 100 упорядоченных сообщений, если используется limitToFirst
, или последние 100 упорядоченных сообщений, если используется limitToLast
.
Используя нашу базу данных фактов о динозаврах и orderBy
, мы можем найти двух самых тяжелых динозавров:
curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="weight"&limitToLast=2&print=pretty'
Аналогично мы можем найти двух самых коротких динозавров, используя limitToFirst
:
curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="height"&limitToFirst=2&print=pretty'
Мы также можем выполнять запросы с ограничением по количеству участников, используя orderBy="$value"
. Если мы хотим создать таблицу лидеров с тремя лучшими участниками соревнований по диноспорту, мы можем сделать следующее:
curl 'https://dinosaur-facts.firebaseio.com/scores.json?orderBy="$value"&limitToLast=3&print=pretty'
Запросы по диапазону
Использование startAt
, endAt
и equalTo
позволяет нам выбирать произвольные начальную и конечную точки для наших запросов. Например, если мы хотим найти всех динозавров ростом не менее трёх метров, мы можем объединить orderBy
и startAt
:
curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="height"&startAt=3&print=pretty'
Мы можем использовать endAt
, чтобы найти всех динозавров, названия которых лексикографически предшествуют птеродактилю:
curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="$key"&endAt="pterodactyl"&print=pretty'
Мы можем объединить startAt
и endAt
, чтобы ограничить оба конца нашего запроса. Следующий пример находит всех динозавров, названия которых начинаются на букву «b»:
curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="$key"&startAt="b"&endAt="b\uf8ff"&print=pretty'
Диапазонные запросы также полезны, когда вам нужно разбить данные на страницы.
Собираем все вместе
Мы можем комбинировать все эти методы для создания сложных запросов. Например, вам нужно найти названия всех динозавров, которые ниже или равны по росту нашему любимому виду — стегозаврам:
MY_FAV_DINO_HEIGHT=`curl "https://dinosaur-facts.firebaseio.com/dinosaurs/stegosaurus/height.json"` curl "https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy=\"height\"&endAt=${MY_FAV_DINO_HEIGHT}&print=pretty"
Как упорядочены данные
В этом разделе объясняется, как упорядочиваются ваши данные при использовании каждого из трех параметров фильтрации.
заказ по
При использовании orderBy
с именем дочернего ключа данные, содержащие указанный дочерний ключ, будут упорядочены следующим образом:
- Сначала идут дочерние элементы с
null
значением для указанного дочернего ключа. - Далее идут дочерние элементы со значением
false
для указанного ключа. Если значениеfalse
есть у нескольких дочерних элементов, они сортируются лексикографически по ключу. - Далее идут дочерние элементы со значением
true
для указанного дочернего ключа. Если значениеtrue
есть у нескольких дочерних элементов, они сортируются лексикографически по ключу. - Далее следуют дочерние элементы с числовым значением, отсортированные по возрастанию. Если несколько дочерних элементов имеют одинаковое числовое значение для указанного дочернего узла, они сортируются по ключу.
- Строки следуют за числами и сортируются лексикографически по возрастанию. Если несколько дочерних элементов имеют одинаковое значение для указанного дочернего узла, они упорядочиваются лексикографически по ключу.
- Объекты идут последними и сортируются лексикографически по ключу в порядке возрастания.
orderBy="$key"
При использовании параметра orderBy="$key"
для сортировки данных данные будут возвращены в порядке возрастания ключа, как показано ниже. Имейте в виду, что ключи могут быть только строками.
- Сначала идут потомки с ключом, который можно проанализировать как 32-битное целое число, отсортированные по возрастанию.
- Далее следуют дочерние элементы со строковым значением в качестве ключа, отсортированные лексикографически в порядке возрастания.
orderBy="$value"
При использовании параметра orderBy="$value"
для сортировки данных дочерние элементы будут упорядочены по их значению. Критерий упорядочивания тот же, что и при сортировке данных по дочернему ключу, за исключением того, что вместо значения указанного дочернего ключа используется значение узла.
orderBy="$priority"
При использовании параметра orderBy="$priority"
для сортировки данных порядок дочерних элементов определяется их приоритетом и ключом следующим образом. Имейте в виду, что значения приоритета могут быть только числами или строками.
- Дети без приоритета (по умолчанию) идут первыми.
- Далее идут дети, приоритет которых определён числом. Они сортируются по приоритету, от меньшего к большему.
- Элементы, приоритет которых — строка, располагаются последними. Они сортируются лексикографически по приоритету.
- Если два дочерних элемента имеют одинаковый приоритет (включая отсутствие приоритета), они сортируются по ключу. Сначала идут числовые ключи (сортируются по номеру), затем — остальные ключи (сортируются лексикографически).
Более подробную информацию о приоритетах см. в справочнике API .
Потоковая передача из REST API
Конечные точки Firebase REST поддерживают протокол EventSource/Server-Sent Events , что упрощает потоковую передачу изменений в одно место в нашей базе данных Firebase.
Чтобы начать трансляцию, нам необходимо сделать следующее:
- Установите заголовок Accept клиента на
text/event-stream
- Уважайте HTTP-перенаправления, в частности код статуса HTTP 307.
- Включите параметр запроса
auth
, если для расположения базы данных Firebase требуется разрешение на чтение.
В ответ сервер будет отправлять именованные события по мере изменения состояния данных по запрошенному URL. Структура этих сообщений соответствует протоколу EventSource:
event: event name data: JSON encoded data payload
Сервер может отправлять следующие события:
помещать | Данные в формате JSON будут представлять собой объект с двумя ключами: path и data. Путь указывает на местоположение относительно URL-адреса запроса. Клиент должен заменить все данные в этом месте своего кэша данными, указанными в сообщении. |
пластырь | Данные в формате JSON будут представлять собой объект с двумя ключами: path и data. Путь указывает на местоположение относительно URL-адреса запроса. Для каждого ключа в данных клиент должен заменить соответствующий ключ в своем кэше данными для этого ключа в сообщении. |
сохранить активность | Данные для этого события отсутствуют, никаких действий не требуется. |
отмена | Данные для этого события равны нулю. Это событие будет отправлено, если Firebase Realtime Database Security Rules приводят к тому, что чтение в запрошенном месте больше не разрешается. |
auth_revoked | Данные для этого события представляют собой строку, указывающую на то, что срок действия учетных данных истек. Это событие будет отправлено, когда предоставленный параметр аутентификации перестанет быть действительным. |
Ниже приведен пример набора событий, которые может отправлять сервер:
// Set your entire cache to {"a": 1, "b": 2} event: put data: {"path": "/", "data": {"a": 1, "b": 2}} // Put the new data in your cache under the key 'c', so that the complete cache now looks like: // {"a": 1, "b": 2, "c": {"foo": true, "bar": false}} event: put data: {"path": "/c", "data": {"foo": true, "bar": false}} // For each key in the data, update (or add) the corresponding key in your cache at path /c, // for a final cache of: {"a": 1, "b": 2, "c": {"foo": 3, "bar": false, "baz": 4}} event: patch data: {"path": "/c", "data": {"foo": 3, "baz": 4}}
Если вы используете Go, ознакомьтесь с Firego — сторонней оболочкой для Firebase REST и Streaming API.