You'll need to do another on()
or once()
for each event inside your current callback, and load the additional data. This process is known as a client-side join. Then within the inner loop you can dispatch the results, either on each load or when all are loaded.
Code (untested, so there may be typos):
usersRef.child(uid).child("events").on("value", snapshot => {
var promises = []
snapshot.forEach(eventSnapshot => {
promises.push(eventsRef.child(eventSnapshot.key).once("value"));
})
Promise.all(promises).then(eventSnapshots => {
// eventSnapshots contains the details of all events
return eventSnapshot.map(eventSnapshot => eventSnapshot.val());
}).then(events => {
dispatch({ type: FETCH_EVENTS, payload: events });
});
})
Alternatively you can duplicate the minimal data for each event under /users/$uid/events/$eventid`. This duplicates data, but prevents the need for client-side joins. This type of read-vs-write trade-off is very common when using NoSQL databases. For strategies for the duplicated data up to date, see How to write denormalized data in Firebase.