Reputation: 375
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
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