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

Чтение данных с помощью 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= , чтобы API REST обернуло возвращаемые данные в указанную вами функцию обратного вызова. Например:

<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 с именем дочернего ключа данные, содержащие указанный дочерний ключ, будут упорядочены следующим образом:

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

orderBy="$key"

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

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

orderBy="$value"

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

orderBy="$приоритет"

При использовании параметра 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. Включите параметр запроса 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.