Извлечение данных

Чтение данных с помощью GET

Чтобы прочитать данные из базы данных Firebase, отправьте запрос GET на ее URL. Продолжим работу с примером блога из предыдущего раздела и прочитаем все данные о записях в блоге:

curl 'https://docs-examples.firebaseio.com/fireblog/posts.json?print=pretty'

При успешном выполнении запроса будет получен код статуса HTTP 200 OK, а ответ будет содержать извлекаемые данные.

Добавление параметров URI

При чтении данных из базы данных Firebase REST API принимает несколько параметров запроса. Ниже перечислены наиболее часто используемые параметры. Полный список приведен в справочнике по 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, логические значения, строки и объекты при использовании 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, чтобы найти всех динозавров, чьи имена предшествуют Pterodactyl в лексикографическом порядке:

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

При использовании orderBy с именем дочернего ключа данные, содержащие указанный дочерний ключ, будут упорядочены следующим образом:

  1. Дочерние элементы со значением null для указанного дочернего ключа будут показаны первыми.
  2. Затем идут дочерние элементы со значением false для указанного дочернего ключа. Если у нескольких дочерних элементов значение false, они сортируются по ключу в лексикографическом порядке.
  3. Затем идут дочерние элементы со значением true для указанного дочернего ключа. Если у нескольких дочерних элементов значение true, они сортируются по ключу в лексикографическом порядке.
  4. Затем идут дочерние элементы с числовыми значениями, отсортированные по возрастанию. Если у нескольких дочерних узлов одинаковое числовое значение, они сортируются по ключу.
  5. Строки следуют за числами и сортируются лексикографически в порядке возрастания. Если у нескольких дочерних узлов одинаковое значение, они упорядочиваются лексикографически по ключу.
  6. Объекты указываются в последнюю очередь и сортируются лексикографически по ключу в порядке возрастания.
Отфильтрованные результаты возвращаются без сортировки. Если порядок данных важен, отсортируйте результаты в приложении после того, как они будут возвращены из Firebase.

orderBy="$key"

Если вы используете параметр orderBy="$key" для сортировки данных, они будут возвращаться в порядке возрастания по ключу, как показано ниже. Помните, что ключи могут быть только строками.

  1. Дочерние элементы с ключом, который можно обработать как 32-битное целое число, идут первыми и сортируются по возрастанию.
  2. Затем идут дочерние элементы со строковым значением в качестве ключа, отсортированные в лексикографическом порядке по возрастанию.

orderBy="$value"

Если вы используете параметр orderBy="$value" для сортировки данных, дочерние элементы будут упорядочены по значению. Критерии упорядочения такие же, как и для данных, упорядоченных по дочернему ключу, за исключением того, что вместо значения указанного дочернего ключа используется значение узла.

orderBy="$priority"

При использовании параметра orderBy="$priority" для сортировки данных порядок дочерних элементов определяется их приоритетом и ключом следующим образом: Помните, что значения приоритета могут быть только числами или строками.

  1. Дочерние элементы без приоритета (по умолчанию) идут первыми.
  2. Затем следуют дочерние элементы, приоритет которых задан числом. Они сортируются по приоритету в порядке возрастания.
  3. Дочерние элементы, приоритет которых задан строкой, идут последними. Они сортируются в лексикографическом порядке по приоритету.
  4. Если у двух дочерних элементов одинаковый приоритет (в том числе если он не задан), они сортируются по ключу. Сначала идут числовые ключи (отсортированные по числовому значению), а затем остальные (отсортированные по алфавиту).

Дополнительную информацию о приоритетах можно найти в документации по API.

Потоковая передача из REST API

Конечные точки Firebase REST поддерживают протокол EventSource/Server-Sent Events, что упрощает передачу изменений в одно место в базе данных Firebase.

Чтобы начать трансляцию, нужно сделать следующее:

  1. Задайте для заголовка Accept клиента значение text/event-stream.
  2. Учитывайте переадресацию HTTP, в частности код статуса HTTP 307
  3. Если для чтения данных из базы данных Firebase требуется разрешение, добавьте параметр запроса auth.

В ответ сервер будет отправлять именованные события по мере изменения состояния данных по запрошенному URL. Структура этих сообщений соответствует протоколу EventSource:

event: event name
data: JSON encoded data payload

Сервер может отправлять следующие события:

поместить Данные в формате JSON будут представлять собой объект с двумя ключами: path и data.
Ключ path указывает на местоположение относительно URL запроса.
Клиент должен заменить все данные в этом местоположении в своем кеше на данные, указанные в сообщении.
patch Данные в формате JSON будут представлять собой объект с двумя ключами: path и data.
Ключ path указывает на местоположение относительно URL запроса.
Для каждого ключа в data клиент должен заменить соответствующий ключ в своем кеше данными для этого ключа в сообщении.
[сообщение] keep-alive Данные для этого события отсутствуют, никаких действий не требуется.
cancel Данные для этого события равны null.
Это событие будет отправлено, если 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 API и Streaming API.