I've started learning NodeJS to use it with Firebase in order to create Functions.
I'm currently stuck because I have nested forEach which must be async.
I'll try to be as understandable as possible.
I have 3 nodes:
- Terminals
- Bookings
- TerminalBookings (which is like a join table)
I have to create a function to get all the terminals with their bookings associated.
So I have to get all the terminals, for each terminal I can get all the terminalbookings associated (the node key is the terminal id and all the values are bookings id).

And then when I have all the terminalbooking, I can get the booking informations in the bookings node.
It look pretty easy to do with Sql but I can figure out how to do it with NodeJS.
Here is what I have (in this state, it's impossible to work, but it looks like what I want to do):
async function getReservationsSnapshotByTerminalId(terminalId) {
const terminalReservationsSnap = await admin.database().ref(`/terminalBookings/${terminalId}`).once('value');
const terminalReservations = Object.keys(terminalReservationsSnap.val());
const reservationsSnapshot = terminalReservations.map((reservationId) => {
return admin.database().ref(`/bookings/${reservationId}`).once('value');
});
return Promise.all(reservationsSnapshot);
}
exports.showTerminalsWithReservations = functions.https.onRequest(async (request, response) => {
let terminals = [];
try {
const terminalsSnapshot = await admin.database().ref('/terminals/').once('value');
terminalsSnapshot.forEach(terminalSnapshot => {
const terminal = new Borne(terminalSnapshot.key, terminalSnapshot.val());
const bookingsSnapshot = await getReservationsSnapshotByTerminalId(terminal.key);
bookingsSnapshot.forEach(booking => {
terminal.bookings.push(booking.val());
});
terminals.push(terminal);
});
} catch(error) {
}
});
But it can't work because of this line :
const bookingsSnapshot = await getReservationsSnapshotByTerminalId(terminal.key);
If I want to use the await, the parent forEach must by async but it's not possible.
I think that I'm not in the right way to handle this feature but I'm stuck, I don't know how to do it.
Feel free to completely rebuild this function if I'm wrong.