【问题标题】:How can I wait for data from firebase database when using Object.keys(x).map() in react native?在 react native 中使用 Object.keys(x).map() 时如何等待来自 firebase 数据库的数据?
【发布时间】:2019-11-22 03:34:31
【问题描述】:

我正在尝试在列表中显示有关组中用户的信息。我想收集关于存储在我的数据库中users/ 下的每个成员的其他信息。

我的代码设法收集信息,但仅限于第一个成员。要加载其他成员的数据,我需要导航回另一个屏幕然后返回。

这是我目前尝试过的:

//members object from group/id/members is passed to this function
//e.g. [{"uid":"abc","type":"admin"},{"uid":"def","type":"member"},{"uid":"ghi","type":"member"}]

getMembersData(members) {
  const membersData = {};

  Object.keys(members).map((key, i) => {
    const member = members[key];

    firebase.database().ref(`users/${member.uid}`).on('value', snap => {
      membersData[member.uid] = {
        'uid': member.uid,
        'username': snap.child('username').val(),
        'imageUrl': snap.child('imageUrl').val(),
        'type': member.type,
      };
    });
  });

  this.setState({ membersData });
}

换句话说,当我导航到成员屏幕时,当我在视图中映射this.state.membersData 时,只会呈现第一个成员的信息,直到我退出屏幕并返回它。

如果我删除了 firebase 内容,代码就可以正常工作。如何解决此问题,以便在我导航到屏幕时加载所有内容?

【问题讨论】:

    标签: firebase react-native firebase-realtime-database


    【解决方案1】:

    我认为您会希望在数据库回调中调用 setState,因为回调是异步,并且在数据最终可用之前不会被调用。 p>

        firebase.database().ref(`users/${member.uid}`).on('value', snap => {
          membersData[member.uid] = {
            'uid': member.uid,
            'username': snap.child('username').val(),
            'imageUrl': snap.child('imageUrl').val(),
            'type': member.type,
          };
           this.setState(membersData);
        });
      });
    

    无法保证获取数据需要多长时间,因此您的代码应该准备好处理可能需要一段时间才能到达的事实(或者如果没有互联网连接,则可能根本不需要)。

    【讨论】:

      【解决方案2】:

      您想在所有数据库调用完成后调用this.setState。如果只需要下载一次数据,可以使用chaining Promises

      因为您使用的是.map(),您可以通过从使用.once('value') 的数据库请求中返回Promise 来实现此目的。在下面的代码中,名为transformPromises 的变量是.map().once('value') 产生的Promise 数组。一旦你有了这一系列的承诺,你就可以使用Promise.all(promiseArray).then(() => {...} 等待它们全部解决。在下面的代码中,这是我们调用this.setState() 来更新用户界面的地方。

      在调用getMembersData() 之前,在加载数据时显示throbber 可能会很有用。

      getMembersData(members) {
        const membersData = {};
      
        let transformPromises = Object.keys(members).map((key, i) => {
          const member = members[key];
      
          return firebase.database().ref(`users/${member.uid}`).once('value')
            .then(snap => {
              membersData[member.uid] = {
                'uid': member.uid,
                'username': snap.child('username').val(),
                'imageUrl': snap.child('imageUrl').val(),
                'type': member.type,
              };
            });
        });
      
        Promise.all(transformPromises)
          .then(() => {
            // all data was downloaded & added successfully.
            this.setState({ membersData });
          })
          .catch((err) => {
            // handle error
            console.error(err)
          });
      }
      

      注意:根据members的形状,您也可以使用以下代码对其进行迭代:

      let transformPromises = members.map(member => {
        return firebase.database().ref(`users/${member.uid}`).once('value')
          .then(snap => {
            membersData[member.uid] = {
              'uid': member.uid,
              'username': snap.child('username').val(),
              'imageUrl': snap.child('imageUrl').val(),
              'type': member.type,
            };
          });
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-24
        • 1970-01-01
        • 2022-08-23
        • 1970-01-01
        • 1970-01-01
        • 2021-11-27
        • 1970-01-01
        相关资源
        最近更新 更多