My guess is that you have a timing issue. .forEach() does not wait for your asynchronous operations to complete before going on to the next iteration (it does not look at the promise that your code is returning from the async callback) and thus after the .forEach() your second array will always be empty after the .forEach() loop because it has not yet been populated (the asynchonous calls in the loop have not yet finished).
So basically, you rarely ever want to use async/await inside a .forEach() callback because the loop doesn't respect it and you have no way of knowing outside the loop when everything is done.
While you don't show a larger context for this code, the usual solution here is to use a regular for lop or a for/of loop which will wait for the await statements and thus you can more easily know when everything is done.
Here's one way to do that:
async function someFunction() {
// other code here
for (let id of candidates) {
try {
console.log('user log ' + id);
const snap2 = await db.doc('communities_data/' + community.id + '/profiles/' + id).get();
const user = snap2.data();
console.log('user ' + user);
if (user !== undefined) {
console.log(user + ' just user');
const reputation = (user.reputation as number);
candidatesWithReputation.push(new UserAndReputation(id, reputation));
} else {
console.log('user undefined ');
};
} catch(e) {
console.log(e);
// decide what to do upon error,
// skip it and proceed?
// stop further processing?
}
}
// candidatesWithReputation should now be valid here
console.log(candidatesWithReputation);
// other code here
}
Note that the containing function has to be declared async to allow you to use await inside the for loop.
For possibly better performance, you could also do all these lookups in parallel and use Promise.all() to see when they're all done:
function someFunction() {
// other code here
Promise.all(candidates.map(id => {
return db.doc('communities_data/' + community.id + '/profiles/' + id).get().then(snap2 => {
return snap2.data();
}).catch(err => {
// decide what to do about an error here
// this implementation skips any queries with error and proceeds with the others
return undefined;
});
})).then(users => {
let candidatesWithReputation = [];
for (user of users) {
if (user !== undefined) {
// I've not seen this "user.reputation as number" syntax?? Typescript?
const reputation = (user.reputation as number);
candidatesWithReputation.push(new UserAndReputation(id, reputation));
}
}
return candidatesWithReputation;
}).then(users => {
// list of users with reputation here
console.log(users);
// further processing here
}).catch(err => {
console.log(err);
});
}