Instructed by Pierre Janineh, it is recommended to utilize the parent
properties within the DocumentReference
and CollectionReference
classes.
Specifically, for each QueryDocumentSnapshot
in the QuerySnapshot
, you can perform the following:
const querySnapshot = await getDocs(userHisRef);
let arr = [];
querySnapshot.forEach((doc) => {
const docRef = doc.ref;
const parentCollectionRef = docRef.parent; // CollectionReference
const immediateParentDocumentRef = parentCollectionRef.parent; // DocumentReference
const grandParentDocumentRef = immediateParentDocumentRef.parent.parent; // DocumentReference
// ...
});
This allows easy access to the DocumentReference
s along with their corresponding id
s of the parent and grandparent documents.
If you require specific data from these parent/grandparent documents such as "position" and "production," a more intricate process is involved... as querying these documents based on their DocumentReference
s becomes necessary.
To accomplish this, one approach involves using Promise.all()
with arrays of promises created within the loop, as depicted:
const querySnapshot = await getDocs(userHisRef);
let arr = [];
const parentsPromises = [];
const grandparentsPromises = [];
querySnapshot.forEach((doc) => {
const docRef = doc.ref;
const parentCollectionRef = docRef.parent; // CollectionReference
const immediateParentDocumentRef = parentCollectionRef.parent; // DocumentReference
const grandParentDocumentRef = immediateParentDocumentRef.parent.parent; // DocumentReference
parentsPromises.push(getDoc(immediateParentDocumentRef));
grandparentsPromises.push(getDoc(grandParentDocumentRef));
// ...
});
const arrayOfParentsDocumentSnapshots = await Promise.all(parentsPromises);
const arrayOfGrandparentsDocumentSnapshots = await Promise.all(grandParentDocumentRef);
This results in two arrays of DocumentSnapshot
s containing the desired data. However, establishing connections with the respective child/grandchild documents may be necessary...
Since the values returned by Promise.all()
are in the order of the Promises passed, utilizing the index of the initial array may assist in linking them with the correct child/grandchild documents, although it may be complex...
Furthermore, if multiple documents exist within a subcollection like "positionhistory," redundant fetching of the same parent and grandparent documents may occur. Managing a list of fetched document IDs can help mitigate this issue but adds another layer of complexity.
Therefore, considering all factors mentioned above, evaluating the feasibility of denormalizing the data could potentially offer a simpler and more efficient solution.