Слушатель базы данных Firebase Realtime внутри цикла не работает должным образом - PullRequest
1 голос
/ 26 мая 2019

Я использую базу данных Firebase Realtime. У меня есть объект, в котором есть все сообщения, созданные всеми нашими пользователями. Этот объект огромен.

Для быстрого отображения сообщений мы дали каждому пользователю объект с соответствующими идентификаторами сообщений.

Структура выглядит так:

/allPosts/$postID/
          : { $postID: {id: $postID, details: '', title: '', timestamp: ''} }

/user/$userID/postsRelevantToThisUser/
              : { $postID: {id: $postID} }

'postsRelevantToThisUser' содержит только идентификаторы сообщений. Мне нужно перебрать каждый из этих идентификаторов и получить всю информацию о сообщении из / allPosts /

В результате клиенту не придется загружать весь объект allPosts, и приложение будет работать намного быстрее.

Для этого я написал следующий код. Он успешно извлекает и отображает только соответствующие сообщения. Всякий раз, когда новый postID добавляется или удаляется из / postsRelevantToThisUser / в базе данных реального времени Firebase, React Native правильно перерисовывает список.

Однако, когда что-либо в / allPosts / $ postID изменяется, например: если изменяется параметр заголовка, он не отражается в представлении.

Какой хороший способ решить эту проблему?

let userPostRef = firebase.database().ref(`/users/${uid}/postsRelevantToThisUser`)

      userPostRef.on('value', (snapshot) => {
        let relPostIds = [];
        let posts = [];

        snapshot.forEach(function(childSnapshot) {
          const {id} = childSnapshot.val();
          relPostIds.push(id);
        })

        relPostIds.map(postId => {
          firebase.database().ref(`allPosts/${postId}`).on('value', (postSnapshot) => {
            let post  = postSnapshot.val()
            posts.push(post);
            this.setState({ postsToRender:posts });
          })

})

1 Ответ

0 голосов
/ 26 мая 2019

Поскольку вы распространяете данные, необходимые для показа сообщений пользователю, по нескольким местам, вам необходимо держать слушателей подключенными к нескольким местам, если вы хотите получать обновления этих данных в реальном времени.

Таким образом, чтобы прослушивать обновления заголовков, вам нужно держать слушателя для каждого /allPosts/$postID, который пользователь может видеть в данный момент. Хотя для отслеживания всех этих слушателей в коде может быть немного придирчиво, на самом деле они достаточно эффективны для самого Firebase, поэтому производительность должна быть хорошей, по крайней мере, до нескольких десятков слушателей (и вряд ли пользователь будет активно читать больше постов сразу).

Кроме того, вы можете дублировать информацию, которую хотите отобразить в виде списка, под узлами /user/$userID/postsRelevantToThisUser каждого пользователя. Таким образом, вы дублируете больше данных, но дополнительные слушатели не понадобятся.

Любой подход хорош, но у меня есть личное предпочтение к последнему, поскольку он упрощает код, который читает данные (что наиболее важно для масштабируемости).

...