Robert Berge
Robert Berge

Reputation: 375

How can I return a JavaScript object of Firebase data in React Native, given an array of uids?

I have an area of my code where users of a group are stored in an array. In some cases, I want to gather additional data on the users.

Here is what I tried so far:

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;
}

I have this code working similarly by setting state and using the firebase .on() function, but I need it to work with .once() and returning the object.

Upvotes: 0

Views: 75

Answers (1)

Renaud Tarnec
Renaud Tarnec

Reputation: 83163

The following should work. Since the once() method is asynchronous and returns a Promise with a DataSnapshot, we use Promise.all() to execute the different queries in parallel.

        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;
        }

Upvotes: 2

Related Questions