I have a fitness dashboard to show activity of users. However the way the database is structured has made this difficult.{collection/document/subcollection/document}
Currently the dashboard does show each user and all the information (i.e. calories) for the previous workout they logged. However some users can do multiple workouts in a set amount of time i.e. 12 hours and there workout and workout information is stored in a subcollection. What i would like to do is for those users who have a subcollection in there document, i would like to query (by set amount of time ) and read all the data in the sub collection for that particular user and add it together (total calories) and show it in the dashboard.
I am having issues doing this because i can retrieving the data and invoking the data. However no errors.
ps. this is for development, actual database is much larger
App.js
function App() {
const [user, setUser] = useState(null);
const [workouts, setworkouts] = useState([]);
const [error, setError] = useState(null);
useEffect(() => {
const unsubscribe = firebase
.auth()
.onAuthStateChanged((user) => setUser(user));
return unsubscribe;
}, []);
useEffect(() => {
const unsubscribe = FirestoreService.getworkoutItems(
(qSnapshot) => {
const updatedworkouts = qSnapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
}));
setworkouts(updatedworkouts);
setError(false);
},
(error) => setError(true)
);
return unsubscribe;
});
useEffect(() => {
const fetchData = async () => {
try {
const qSnapshot = await getDocs(collection(db, "workouts"));
let allDocs = [];
qSnapshot.forEach((doc) => {
allDocs.push({ id: doc.id, ...doc.data() });
});
for (const item of allDocs) {
const time = 12;
const timeDiff = moment(new Date()).subtract(time, "hours")._d;
const qSnap = await getDocs(
collection(db, `workouts/${item.id}/Extra`).where(
"time",
">=",
timeDiff
)
);
let totalCount = 0;
totalCount += qSnap.calories;
console.log(qSnap);
console.log(totalCount);
let allQDocs = [];
if (!qSnap.empty) {
qSnap.forEach((doc) => {
allQDocs.push({
id: doc.id,
calories: doc.data().calories,
...doc.data(),
});
console.log(allQDocs);
console.log(allQDocs[0].calories);
});
} else {
}
}
} catch (err) {
console.log(err);
}
};
fetchData();
}, []);
return (
<div>
<Container>
<Header />
<Divider horizontal section>
Fitness Monitor
</Divider>
{!error && user ? (
<Card.Group itemsPerRow="8">
{workouts &&
workouts.map((workout) => {
return <Cards key={workout.id} workout={workout} />;
})}
</Card.Group>
) : (
<h2> sign in </h2>
)}
</Container>
</div>
);
}
export default App;
firebase.js
const firebaseConfig = {
XXXXXXXXXXXXXXXXX,
};
firebase.initializeApp(firebaseConfig);
const app = initializeApp(firebaseConfig);
export const db = getFirestore(app);
export const auth = firebase.auth();
const provider = new firebase.auth.GoogleAuthProvider();
provider.setCustomParameters({ prompt: "select_account" });
export const signInWithGoogle = () => auth.signInWithPopup(provider);
export const getworkoutItems = (snapshot, error) => {
const ref = collection(db, "workouts");
const query = query(ref);
return onSnapshot(query, snapshot, error);
};
[![Structure of database for one workout user][1]][1]
[![Structure of database for a user who has a subcollection of workouts][2]][2]
Structure of database for one workout user
[1]: https://i.stack.imgur.com/1AKy9.png
Structure of database for a user who has a subcollection of workouts
[2]: https://i.stack.imgur.com/62giC.png
What I have tried:
Have tried using type literals