Получить ссылку на базу данных
Для чтения или записи данных из базы данных вам необходим экземпляр 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() | Упорядочить результаты по дочерним значениям. |
Вы можете использовать только один метод order-by за раз. Вызов метода order-by несколько раз в одном запросе приводит к ошибке.
В следующем примере показано, как можно получить список лучших публикаций пользователя, отсортированный по количеству звезд:
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, вы можете прочитать больше о нем в Structure Your Database .
Вызов метода 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() | Возвращает элементы, равные указанному ключу или значению, в зависимости от выбранного метода сортировки. |
В отличие от методов order-by, вы можете комбинировать несколько функций limit или range. Например, вы можете комбинировать методы 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()
для выбора произвольных начальных, конечных и эквивалентных точек для запросов. Это может быть полезно для разбиения данных на страницы или поиска элементов с потомками, имеющими определенное значение.
Как упорядочиваются данные запроса
В этом разделе объясняется, как данные сортируются каждым из методов сортировки в классе Query
.
orderByChild
При использовании orderByChild()
данные, содержащие указанный дочерний ключ, упорядочиваются следующим образом:
- Сначала идут потомки с
null
значением для указанного дочернего ключа. - Далее идут дети со значением
false
для указанного дочернего ключа. Если несколько детей имеют значениеfalse
, они сортируются лексикографически по ключу. - Далее идут дети со значением
true
для указанного дочернего ключа. Если несколько детей имеют значениеtrue
, они сортируются лексикографически по ключу. - Далее следуют дети с числовым значением, отсортированные по возрастанию. Если несколько детей имеют одинаковое числовое значение для указанного дочернего узла, они сортируются по ключу.
- Строки идут после чисел и сортируются лексикографически в порядке возрастания. Если несколько дочерних элементов имеют одинаковое значение для указанного дочернего узла, они упорядочиваются лексикографически по ключу.
- Объекты располагаются последними и сортируются лексикографически по ключу в порядке возрастания.
orderByKey
При использовании orderByKey()
для сортировки данных данные возвращаются в порядке возрастания ключа.
- Сначала идут потомки с ключом, который можно проанализировать как 32-битное целое число, отсортированные в порядке возрастания.
- Далее следуют дочерние элементы со строковым значением в качестве ключа, отсортированные лексикографически в порядке возрастания.
orderByValue
При использовании orderByValue()
дети сортируются по их значению. Критерии упорядочивания такие же, как в orderByChild()
, за исключением того, что вместо значения указанного дочернего ключа используется значение узла.
Отсоединить слушателей
Обратные вызовы удаляются путем вызова метода off()
в ссылке на базу данных Firebase.
Вы можете удалить одного слушателя, передав его в качестве параметра off()
. Вызов off()
для местоположения без аргументов удаляет всех слушателей в этом местоположении.
Вызов off()
для родительского прослушивателя не приводит к автоматическому удалению прослушивателей, зарегистрированных на его дочерних узлах; off()
также необходимо вызвать для любых дочерних прослушивателей, чтобы удалить обратный вызов.