Добавить данные во вложенный массив foreach, используя React и Firebase / Firestore - PullRequest
1 голос
/ 28 марта 2019

У меня есть несколько вложенных вызовов при использовании Firestore.При этом они полагаются на использование .then (), потому что они являются сетевыми вызовами.Они кажутся настолько вложенными, что перестают иметь доступ к списку, который я ищу для обновления, который называется «сообщения».

Из-за этого беспорядка я обновляю состояние на каждой итерации цикла, которая дико не работает.

Как я могу передать массив сообщений, указанный в качестве отправной точки?:

Кстати, этот метод onCollectionUpdate связан с моим конструктором следующим образом:этот).Спасибо!

onCollectionUpdate = querySnapshot => {
    const messages = [];
    querySnapshot.forEach(doc => {
      const { _id, text, createdAt, user } = doc.data();
      var userId = user.id
      var userRef = firebase.firestore().collection('users').doc(userId)
      userRef.get().then(data => {
        var user = data.data()
        var userObject = {
            _id: userId,
            name: user.name,
            avatar: user.profilePictureURL
        }
        var newMessage = {
          _id,
          text,
          createdAt: new Date(createdAt.seconds),
          user: userObject
        }
        this.setState(prevState => ({messages: [...prevState.messages,newMessage]}))

        messages.push() //Not working. By time it reaches set state below (outside of the loops) it is empty.
      })
    })
    this.setState({
      messages,
      loading: false,
    });
  }

1 Ответ

2 голосов
/ 28 марта 2019

Вот решение

onCollectionUpdate = querySnapshot => {
    var promises = [];
    const messages = [];

    querySnapshot.forEach(doc => {
      const { _id, text, createdAt, user } = doc.data();
      var userId = user.id
      var userRef = firebase.firestore().collection('users').doc(userId)
      promises.push(
        userRef.get()
        .then(data => {
          var user = data.data()
          var userObject = {
            _id: userId,
            name: user.name,
            avatar: user.profilePictureURL
          }
          return {
            _id,
            text,
            createdAt: new Date(createdAt.seconds),
            user: userObject
          }
        })
      )
    })

    Promise.all(promises).then(newMessages=> {
        this.setState(prevState => {
            return {
                messages: [...prevState.messages, ...newMessages],
                loading: false,
              }
        })
    })
  }

Как только все вы получите все ответы, вы вызываете setState один раз. Надеюсь, это то, что вы хотели:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...