Работа со списками данных в Интернете

Получите ссылку на базу данных.

To read or write data from the database, you need an instance of firebase.database.Reference :

Web

import { getDatabase } from "firebase/database";

const database = getDatabase();

Web

var database = firebase.database();

Списки для чтения и письма

Добавить к списку данных

В многопользовательских приложениях метод push() используется для добавления данных в список. Метод push() генерирует уникальный ключ каждый раз, когда к указанной ссылке Firebase добавляется новый дочерний элемент. Используя эти автоматически генерируемые ключи для каждого нового элемента в списке, несколько клиентов могут одновременно добавлять дочерние элементы в одно и то же место без конфликтов записи. Уникальный ключ, генерируемый методом push() , основан на метке времени, поэтому элементы списка автоматически упорядочиваются в хронологическом порядке.

Вы можете использовать ссылку на новые данные, возвращаемые методом push() , чтобы получить значение автоматически сгенерированного ключа дочернего элемента или установить данные для дочернего элемента. Свойство .key ссылки на метод push() содержит автоматически сгенерированный ключ.

You can use these auto-generated keys to simplify flattening your data structure. For more information, see the data fan-out example .

For example, push() could be used to add a new post to a list of posts in a social application:

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 Listen for items being removed from a list. This event is triggered when an immediate child is removed.The snapshot passed to the callback block contains the data for the removed child.
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);
});

Обращайте внимание на важные события.

While listening for child events is the recommended way to read lists of data, there are situations listening for value events on a list reference is useful.

Attaching a value observer to a list of data will return the entire list of data as a single snapshot which you can then loop over to access individual children.

Even when there is only a single match for the query, the snapshot is still a list; it just contains a single item. To access the item, you need to loop over the result:

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();
    // ...
  });
});

This pattern can be useful when you want to fetch all children of a list in a single operation, rather than listening for additional child added events.

Сортировка и фильтрация данных

С помощью класса Realtime Database Query можно получать данные, отсортированные по ключу, по значению или по значению дочернего элемента. Также можно отфильтровать отсортированный результат, выбрав определенное количество результатов или диапазон ключей или значений.

Сортировка данных

To retrieve sorted data, start by specifying one of the order-by methods to determine how results are ordered:

Метод Использование
orderByChild() Order results by the value of a specified child key or nested child path.
orderByKey() Сортировать результаты по дочерним ключам.
orderByValue() Сортировать результаты по значениям дочерних элементов.

You can only use one order-by method at a time. Calling an order-by method multiple times in the same query throws an error.

The following example demonstrates how you could retrieve a list of a user's top posts sorted by their star count:

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",
  }
},

In this case, we can order our list elements by values nested under the metrics key by specifying the relative path to the nested child in our orderByChild() call.

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() Sets the maximum number of items to return from the beginning of the ordered list of results.
limitToLast() Устанавливает максимальное количество элементов, возвращаемых с конца упорядоченного списка результатов.
startAt() Возвращает элементы, большие или равные указанному ключу или значению, в зависимости от выбранного метода сортировки.
startAfter() Return items greater than the specified key or value depending on the order-by method chosen.
endAt() Возвращает элементы, меньшие или равные указанному ключу или значению, в зависимости от выбранного метода сортировки.
endBefore() Return items less than the specified key or value depending on the order-by method chosen.
equalTo() Возвращает элементы, равные указанному ключу или значению, в зависимости от выбранного метода сортировки.

В отличие от методов сортировки, вы можете комбинировать несколько функций ограничения или диапазона. Например, вы можете объединить методы startAt() и endAt() , чтобы ограничить результаты заданным диапазоном значений.

Ограничьте количество результатов

Методы limitToFirst() и limitToLast() позволяют установить максимальное количество дочерних элементов, синхронизируемых для данного события. Например, если вы используете limitToFirst() для установки лимита в 100, вы изначально получите только до 100 событий child_added . Если в вашей базе данных Firebase хранится менее 100 элементов, событие child_added будет срабатывать для каждого элемента.

As items change, you receive child_added events for items that enter the query and child_removed events for items that drop out of it so that the total number stays at 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() данные, содержащие указанный дочерний ключ, упорядочиваются следующим образом:

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

orderByKey

При использовании orderByKey() для сортировки данных, данные возвращаются в порядке возрастания по ключу.

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

orderByValue

При использовании orderByValue() дочерние узлы упорядочиваются по их значению. Критерии сортировки такие же, как и в orderByChild() , за исключением того, что вместо значения указанного ключа дочернего узла используется значение самого узла.

Отключить слушателей

Обратные вызовы удаляются путем вызова метода off() в ссылке на вашу базу данных Firebase.

Удалить отдельный обработчик событий можно, передав его в качестве параметра функции off() . Вызов функции off() для указанного местоположения без аргументов удалит все обработчики событий в этом местоположении.

Вызов метода off() для родительского обработчика событий не приводит к автоматическому удалению обработчиков, зарегистрированных на его дочерних узлах; off() также необходимо вызвать для всех дочерних обработчиков событий, чтобы удалить функцию обратного вызова.

Следующие шаги