0

My data model:

A Trip has a sub collection Rides and references the trip with tripId

A ride has an experience: string which I'd like to filter on.

So I thought to query the SubCollection Rides

export const getTripsByExperience = async (experience: EXPERIENCES) => {
  const ridesQuery = query(
    collectionGroup(db, 'rides'),
    where('experience', '==', experience)
  );
  const querySnapshot = await getDocs(ridesQuery);
  let trips: Trip[] = [];
  querySnapshot.forEach(async (rideDoc) => {
    const ride = rideDoc.data();
    const tripSnapshot = await getDoc(doc(db, 'trips', ride.id));
    trips.push({ ...tripSnapshot.data(), id: tripSnapshot.id });
  });
  return trips
}

When I console.log this out right after trips.push trips.length gets incrementally bigger, but when the loop finishes, the function returns an empty array

What is the right approach here to get the trips filtered by rides.experience?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Flov
  • 1,527
  • 16
  • 25

1 Answers1

2

forEach does not work with async, just convert it to the map instead.

const tripsPromises = querySnapshot.docs.map(async (rideDoc) => {
    const ride = rideDoc.data();
    const tripSnapshot = await getDoc(doc(db, 'trips', ride.id));
    return { ...tripSnapshot.data(), id: tripSnapshot.id };
});

const trips: Trip[] = await Promise.all(tripsPromises);

Here is a similar question with more details and examples in the answers: Using async/await with a forEach loop

Update: The documents can be accessed as an array via the "docs" property or enumerated using the forEach method as per https://firebase.google.com/docs/reference/node/firebase.firestore.QuerySnapshot

Sergey Sosunov
  • 4,124
  • 2
  • 11
  • 15
  • I see... This won't work though `.map` doesn't exist on querySnapshot. However, I was able to use `querySnapshot.docs` with a for loop and this works. It's strange that I don't read nothing about this in the docs. There forEach is always used. – Flov Jul 21 '22 at 20:18
  • 1
    forEach is used in docs due to in the docs they do not execute any async operations if i remember correctly, they just do something (small, like logging) there – Sergey Sosunov Jul 21 '22 at 20:26