Получите ссылку на базу данных.
Для чтения или записи данных из базы данных необходим экземпляр объекта firebase.database.Reference :
Web
import { getDatabase } from "firebase/database"; const database = getDatabase();
Web
var database = firebase.database();
Списки для чтения и письма
Добавить к списку данных
В многопользовательских приложениях метод push() используется для добавления данных в список. Метод push() генерирует уникальный ключ каждый раз, когда к указанной ссылке Firebase добавляется новый дочерний элемент. Используя эти автоматически генерируемые ключи для каждого нового элемента в списке, несколько клиентов могут одновременно добавлять дочерние элементы в одно и то же место без конфликтов записи. Уникальный ключ, генерируемый методом push() , основан на метке времени, поэтому элементы списка автоматически упорядочиваются в хронологическом порядке.
Вы можете использовать ссылку на новые данные, возвращаемые методом push() , чтобы получить значение автоматически сгенерированного ключа дочернего элемента или установить данные для дочернего элемента. Свойство .key ссылки на метод push() содержит автоматически сгенерированный ключ.
Вы можете использовать эти автоматически сгенерированные ключи для упрощения преобразования структуры данных в плоскую. Для получения дополнительной информации см. пример разветвления данных.
Например, push() можно использовать для добавления нового сообщения в список сообщений в социальном приложении:
Web
import { getDatabase, ref, push, set } from "firebase/database"; // Create a new post reference with an auto-generated id const db = getDatabase(); const postListRef = ref(db, 'posts'); const newPostRef = push(postListRef); set(newPostRef, { // ... });
Web
// Create a new post reference with an auto-generated id var postListRef = firebase.database().ref('posts'); var newPostRef = postListRef.push(); newPostRef.set({ // ... });
Слушайте новости о детских мероприятиях
События, связанные с дочерними узлами, запускаются в ответ на определенные операции, происходящие с дочерними узлами, например, добавление нового дочернего узла с помощью метода push() или обновление дочернего узла с помощью метода update() .
| Событие | Типичное использование |
|---|---|
child_added | Получает списки элементов или отслеживает добавления элементов в список. Это событие срабатывает один раз для каждого существующего дочернего элемента, а затем снова каждый раз, когда к указанному пути добавляется новый дочерний элемент. Обработчику передается снимок, содержащий данные нового дочернего элемента. |
child_changed | Отслеживайте изменения элементов в списке. Это событие срабатывает всякий раз, когда изменяется дочерний узел. Это включает в себя любые изменения потомков дочернего узла. Снимок, передаваемый обработчику событий, содержит обновленные данные для дочернего узла. |
child_removed | Отслеживайте удаление элементов из списка. Это событие срабатывает при удалении непосредственного дочернего элемента. Снимок, передаваемый в блок обратного вызова, содержит данные удаленного дочернего элемента. |
child_moved | Отслеживайте изменения порядка элементов в упорядоченном списке. События child_moved всегда следуют за событием child_changed , которое вызвало изменение порядка элемента (в зависимости от используемого метода сортировки). |
Каждый из этих методов в совокупности может быть полезен для отслеживания изменений в конкретном узле базы данных. Например, приложение для ведения блога может использовать эти методы вместе для мониторинга активности в комментариях к публикации, как показано ниже:
Web
import { getDatabase, ref, onChildAdded, onChildChanged, onChildRemoved } from "firebase/database"; const db = getDatabase(); const commentsRef = ref(db, 'post-comments/' + postId); onChildAdded(commentsRef, (data) => { addCommentElement(postElement, data.key, data.val().text, data.val().author); }); onChildChanged(commentsRef, (data) => { setCommentValues(postElement, data.key, data.val().text, data.val().author); }); onChildRemoved(commentsRef, (data) => { deleteComment(postElement, data.key); });
Web
var commentsRef = firebase.database().ref('post-comments/' + postId); commentsRef.on('child_added', (data) => { addCommentElement(postElement, data.key, data.val().text, data.val().author); }); commentsRef.on('child_changed', (data) => { setCommentValues(postElement, data.key, data.val().text, data.val().author); }); commentsRef.on('child_removed', (data) => { deleteComment(postElement, data.key); });
Обращайте внимание на важные события.
Хотя прослушивание событий дочерних элементов является рекомендуемым способом чтения списков данных, в некоторых ситуациях полезно прослушивать события значений по ссылке на список.
Прикрепление наблюдателя value к списку данных вернет весь список данных в виде единого снимка, по которому затем можно будет пройтись циклом для доступа к отдельным дочерним элементам.
Даже если для запроса найдено только одно совпадение, снимок все равно представляет собой список; он просто содержит один элемент. Чтобы получить доступ к элементу, необходимо пройтись циклом по результату:
Web
import { getDatabase, ref, onValue } from "firebase/database"; const db = getDatabase(); const dbRef = ref(db, '/a/b/c'); onValue(dbRef, (snapshot) => { snapshot.forEach((childSnapshot) => { const childKey = childSnapshot.key; const childData = childSnapshot.val(); // ... }); }, { onlyOnce: true });
Web
ref.once('value', (snapshot) => { snapshot.forEach((childSnapshot) => { var childKey = childSnapshot.key; var childData = childSnapshot.val(); // ... }); });
Этот шаблон может быть полезен, когда вам нужно получить всех дочерних элементов списка за одну операцию, вместо того чтобы отслеживать события добавления дополнительных дочерних элементов.
Сортировка и фильтрация данных
С помощью класса Realtime Database Query можно получать данные, отсортированные по ключу, по значению или по значению дочернего элемента. Также можно отфильтровать отсортированный результат, выбрав определенное количество результатов или диапазон ключей или значений.
Сортировка данных
Для получения отсортированных данных сначала укажите один из методов сортировки, чтобы определить, как будут упорядочены результаты:
| Метод | Использование |
|---|---|
orderByChild() | Результаты сортировки определяются по значению указанного дочернего ключа или вложенного дочернего пути. | orderByKey() | Сортировать результаты по дочерним ключам. |
orderByValue() | Сортировать результаты по значениям дочерних элементов. |
Одновременно можно использовать только один метод сортировки. Многократный вызов метода сортировки в одном запросе приведет к ошибке.
Следующий пример демонстрирует, как можно получить список лучших постов пользователя, отсортированных по количеству звезд:
Web
import { getDatabase, ref, query, orderByChild } from "firebase/database"; import { getAuth } from "firebase/auth"; const db = getDatabase(); const auth = getAuth(); const myUserId = auth.currentUser.uid; const topUserPostsRef = query(ref(db, 'user-posts/' + myUserId), orderByChild('starCount'));
Web
var myUserId = firebase.auth().currentUser.uid; var topUserPostsRef = firebase.database().ref('user-posts/' + myUserId).orderByChild('starCount');
Это определяет запрос, который в сочетании с дочерним обработчиком синхронизирует клиент с сообщениями пользователя из пути в базе данных на основе его идентификатора пользователя, упорядоченного по количеству звезд, полученных каждым сообщением. Этот метод использования идентификаторов в качестве ключей индекса называется «расширение данных» (data fan out), подробнее об этом можно прочитать в статье «Структурирование базы данных» .
Вызов метода orderByChild() указывает ключ дочернего элемента, по которому следует сортировать результаты. В данном случае записи сортируются по значению соответствующего дочернего элемента "starCount" . Запросы также можно сортировать по вложенным дочерним элементам, если у вас есть данные, которые выглядят следующим образом:
"posts": {
"ts-functions": {
"metrics": {
"views" : 1200000,
"likes" : 251000,
"shares": 1200,
},
"title" : "Why you should use TypeScript for writing Cloud Functions",
"author": "Doug",
},
"android-arch-3": {
"metrics": {
"views" : 900000,
"likes" : 117000,
"shares": 144,
},
"title" : "Using Android Architecture Components with Firebase Realtime Database (Part 3)",
"author": "Doug",
}
},В этом случае мы можем упорядочить элементы списка по значениям, вложенным под ключом metrics , указав относительный путь к вложенному дочернему элементу в вызове функции orderByChild() .
Web
import { getDatabase, ref, query, orderByChild } from "firebase/database"; const db = getDatabase(); const mostViewedPosts = query(ref(db, 'posts'), orderByChild('metrics/views'));
Web
var mostViewedPosts = firebase.database().ref('posts').orderByChild('metrics/views');
Для получения дополнительной информации о порядке упорядочивания других типов данных см. раздел «Как упорядочиваются данные запроса» .
Фильтрация данных
Для фильтрации данных при построении запроса можно комбинировать любой из методов ограничения или диапазона с методом сортировки.
| Метод | Использование |
|---|---|
limitToFirst() | Устанавливает максимальное количество элементов, возвращаемых с начала упорядоченного списка результатов. |
limitToLast() | Устанавливает максимальное количество элементов, возвращаемых с конца упорядоченного списка результатов. |
startAt() | Возвращает элементы, большие или равные указанному ключу или значению, в зависимости от выбранного метода сортировки. |
startAfter() | Возвращает элементы, превышающие указанный ключ или значение, в зависимости от выбранного метода сортировки. |
endAt() | Возвращает элементы, меньшие или равные указанному ключу или значению, в зависимости от выбранного метода сортировки. |
endBefore() | Возвращает количество элементов меньше указанного ключа или значения в зависимости от выбранного метода сортировки. |
equalTo() | Возвращает элементы, равные указанному ключу или значению, в зависимости от выбранного метода сортировки. |
В отличие от методов сортировки, вы можете комбинировать несколько функций ограничения или диапазона. Например, вы можете объединить методы startAt() и endAt() , чтобы ограничить результаты заданным диапазоном значений.
Ограничьте количество результатов
Методы limitToFirst() и limitToLast() позволяют установить максимальное количество дочерних элементов, синхронизируемых для данного события. Например, если вы используете limitToFirst() для установки лимита в 100, вы изначально получите только до 100 событий child_added . Если в вашей базе данных Firebase хранится менее 100 элементов, событие child_added будет срабатывать для каждого элемента.
По мере изменения элементов вы получаете события child_added для элементов, которые попадают в запрос, и события child_removed для элементов, которые из него выпадают, так что общее количество остается равным 100.
В следующем примере показано, как в тестовом приложении для ведения блога определяется запрос для получения списка из 100 самых последних сообщений всех пользователей:
Web
import { getDatabase, ref, query, limitToLast } from "firebase/database"; const db = getDatabase(); const recentPostsRef = query(ref(db, 'posts'), limitToLast(100));
Web
var recentPostsRef = firebase.database().ref('posts').limitToLast(100);
В этом примере определен только запрос; для фактической синхронизации данных необходимо прикрепить к нему слушатель .
Фильтрация по ключу или значению
Вы можете использовать startAt() , startAfter() , endAt() , endBefore() и equalTo() для выбора произвольных начальных, конечных и эквивалентных точек для запросов. Это может быть полезно для постраничной навигации данных или поиска элементов с дочерними элементами, имеющими определенное значение.
Как упорядочиваются данные запроса
В этом разделе объясняется, как данные сортируются каждым из методов ORDER BY в классе Query .
orderByChild
При использовании функции orderByChild() данные, содержащие указанный дочерний ключ, упорядочиваются следующим образом:
- В первую очередь идут дочерние элементы, у которых указанный ключ дочернего элемента имеет
nullзначение. - Далее следуют дочерние элементы со значением
falseдля указанного ключа дочернего элемента. Если несколько дочерних элементов имеют значениеfalse, они сортируются лексикографически по ключу. - Далее следуют дочерние элементы, у которых для указанного ключа дочернего элемента значение равно
true. Если несколько дочерних элементов имеют значениеtrue, они сортируются лексикографически по ключу. - Далее следуют дочерние узлы с числовым значением, отсортированные в порядке возрастания. Если несколько дочерних узлов имеют одинаковое числовое значение для указанного дочернего узла, они сортируются по ключу.
- Строки следуют за числами и сортируются лексикографически в порядке возрастания. Если несколько дочерних узлов имеют одинаковое значение для указанного дочернего узла, они упорядочиваются лексикографически по ключу.
- Объекты располагаются в самом конце и сортируются лексикографически по ключу в порядке возрастания.
orderByKey
При использовании orderByKey() для сортировки данных, данные возвращаются в порядке возрастания по ключу.
- В порядке возрастания первыми идут дочерние элементы, ключ которых может быть интерпретирован как 32-битное целое число.
- Далее следуют дети, у которых в качестве ключа используется строковое значение, отсортированные лексикографически в порядке возрастания.
orderByValue
При использовании orderByValue() дочерние узлы упорядочиваются по их значению. Критерии сортировки такие же, как и в orderByChild() , за исключением того, что вместо значения указанного ключа дочернего узла используется значение самого узла.
Отключить слушателей
Обратные вызовы удаляются путем вызова метода off() в ссылке на вашу базу данных Firebase.
Удалить отдельный обработчик событий можно, передав его в качестве параметра функции off() . Вызов функции off() для указанного местоположения без аргументов удалит все обработчики событий в этом местоположении.
Вызов метода off() для родительского обработчика событий не приводит к автоматическому удалению обработчиков, зарегистрированных на его дочерних узлах; off() также необходимо вызвать для всех дочерних обработчиков событий, чтобы удалить функцию обратного вызова.