【问题标题】:How can I return a JavaScript object of Firebase data in React Native, given an array of uids?给定一组 uid,如何在 React Native 中返回 Firebase 数据的 JavaScript 对象?
【发布时间】:2019-11-28 21:55:43
【问题描述】:

我的代码中有一个区域,其中组的用户存储在一个数组中。在某些情况下,我想收集有关用户的其他数据。

这是我目前尝试过的:

async getMembersData(groupUid) {
    const members = await this.getMembers(groupUid);
    var membersData = {};

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

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

    return membersData;
}

我通过设置状态和使用 firebase .on() 函数使这段代码的工作方式类似,但我需要它与 .once() 一起工作并返回对象。

【问题讨论】:

  • 您可能认为它适用于on(),但实际上它会在第一次调用getMembersData 时返回一个空对象。您需要处理代码是异步的这一事实,例如使用 Renaud 回答中的方法。

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


【解决方案1】:

以下应该有效。由于once() 方法是异步的并返回带有DataSnapshot 的Promise,因此我们使用Promise.all() 来并行执行不同的查询。

        async getMembersData(groupUid) {

            const members = await this.getMembers(groupUid);

            var membersData = {};

            const promises = [];
            const memberTypes = [];

            Object.keys(members).map((key, i) => {
                const member = members[key];
                promises.push(firebase.database().ref(`users/${member.uid}`).once('value'));
                memberTypes.push(member.type);
            });

            const memberSnapshotsArray = await Promise.all(promises);

            memberSnapshotsArray.forEach((snap, index) => {
              //You may check here if the DataSnapshot exists (snap.exists())                  

              const memberUid = snap.key;
              membersData[memberUid]  = {
                'uid': memberUid,
                'username': snap.child('username').val(),
                'imageUrl': snap.child('imageUrl').val(),
                'type': memberTypes[index]
              };  

              //Note that returned values from Promise.all() will be in order of the Promises passed, regardless of completion order
              //This is why we can use memberTypes[index]

            });             

            return membersData;
        }

【讨论】:

  • 这不会编译,因为 await 不能位于未声明为 async 的函数体中(您将一个新函数作为回调传递给 map)。即使您将其设为异步,map 也会立即返回,而不是等待回调返回的 promise 解决,因此它只会返回空 membersData。
  • @DougStevenson 感谢您指出问题 Doug!显然我写答案时太快了......我已经使用Promise.all()对其进行了调整。
猜你喜欢
  • 2018-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多