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

Чтение данных с помощью 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 , логические, строковые и объектные значения при использовании 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="$ключ"

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

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

orderBy="$значение"

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

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

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

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

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

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

Конечные точки REST Firebase поддерживают протокол 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 будут представлять собой объект с двумя ключами: путь и данные.
Путь указывает на местоположение относительно URL-адреса запроса.
Клиент должен заменить все данные в этом месте своего кэша данными, указанными в сообщении.
пластырь Данные в формате JSON будут представлять собой объект с двумя ключами: путь и данные.
Путь указывает на местоположение относительно 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 — стороннюю оболочку API Firebase REST и Streaming.