I have a database structure attempt to deal with the classic events / participants schema. I have events with participants, and participants attend events. I believe for a query that delivers details of all events a participant has attended to scale properly, it is not good practice to query all the events and filter them to find a participant. Comments are welcome on this view. The users are in one collection and the events are in another. So I have added a subEvent subcollection to users to store the document ref for the events they participate in. I now want to retrieve those document references from a query in users and retrieve the detailed event records in the second query in events. Here’s the scheme with the event ids in both.
My first query looks like this:-
const asnapshot = await db.collection("users").doc(_req.params.id).collection("subEvents").get();
And the second:-
const doc = await db.collection("events").doc(results_from_asnapshot).get();
Where results_from_asnapshot
is just a placeholder for the document ids from the first. Note I mean ids plural as the first query will return multiple results, and the second one only by one. To deal with this I am attempting to create a result from a snapshot that contains all the events, and then loop though them in the second query to build a complete detailed list of events that the participant has attended.
Several problems have emerged that I would like help with. One is the output from the first query that is acceptable in the second, and there seem to be conflicting answers as to what will work see. Some say a string like this will work, and others do not. I had doc.data() is not a function
error plaguing me until for no reason, on a test query like this it inexplicably went away.
const doc = await db.collection("events").doc("0adFOpcHZZONGDu3Qw7n").get();
And secondly how to properly loop the second query. And the third issue is why the second query, which is preceded by await, does it warn in the linter that await will be ignored. I know that one query must end before the next can start so why not use await? Here goes my vastly flawed attempt, one of the hundreds that I have tried, you will note it is a node.js firebase function:
const functions = require("firebase-functions");
const express = require("express");
const admin = require("firebase-admin");
admin.initializeApp();
const appWhen = express();
const db = admin.firestore();
appWhen.get("/eventsDetails/:id", async (_req, res) => {
functions.logger.log("Function started");
const snapshot = await db.collection("users").
doc(_req.params.id).collection("subEvents").get();
const userevents = [];
snapshot.forEach((doc) => {
const id = doc.id;
const data = doc.data().eventID;
userevents.push({id, ...data});
});
functions.logger.log("userevents", JSON.stringify(userevents));//EDIt Clearer log
const eventlist = [];
userevents.forEach((event) => {
const doc = db.collection("events").doc(event).get();// Edit removed await
const id = doc.id;
const eventData = doc.data();
functions.logger.log("eventData", eventData);
eventlist.push({id, ...eventData});
});
res.status(200).send(JSON.stringify({id: id, ...eventlist}));
});
Any help most welcome.