I am writing a React/Redux app that uses Firebase Auth/Firestore to keep track of a user's gym exercises. I have Redux Form to handle data submission and I have the below example data structure I want to achieve in Firestore:
users {
id {
name: 'John Smith'
uid: 'k1s7fxo9oe2ls9u' (es from Firebase Auth)
exercises: {
{
name: 'Bench Press',
sets: 3,
reps: 10,
lbs: 100,
}
}
}
}
However, I can't figure out how to keep adding new exercise objects to the exercises subcollection (in Firestore I guess it would be a field type of map). What I want to do is have new objects in "exercises" as the user submits new forms. So for example, if the user wanted to add a Deadlift exercise, it would look like the below:
users {
id {
name: 'John Smith'
uid: 'k1s7fxo9oe2ls9u' (es from Firebase Auth)
exercises: {
{
name: 'Bench Press',
sets: 3,
reps: 10,
lbs: 100,
},
{
name: 'Deadlift',
sets: 3,
reps: 12,
lbs: 120,
}
}
}
}
Calling db.collection('users').doc(doc.id).add({"exercises": values});
just updates the Bench Press object that's there already rather than adding a new one on submission of the form.
But calling db.collection('users').doc(doc.id).add({"exercises": values});
gives me this error: Uncaught (in promise) TypeError: _firebase__WEBPACK_IMPORTED_MODULE_3__.default.collection(...).doc(...).add is not a function.
I've been struggling with this for quite a while, any help is hugely appreciated.
This is my ponent:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Field, reduxForm } from 'redux-form';
import db from '../../../firebase';
import '@firebase/firestore';
import { store } from '../../../App';
const formSubmit = (values)=> {
const currentUserId = store.getState().auth.uid;
db.collection("users").get().then((usersSnapshot) => {
usersSnapshot.forEach((doc) => {
// looking for the current user and then updating their data
if(doc.data().uid === currentUserId) {
db.collection('users').doc(doc.id).add({
"exercises": values,
});
}
});
});
}
let ExercisesForm = ({ handleSubmit }) => (
<form onSubmit={handleSubmit(formSubmit)}>
<div>
<Field name="name" ponent="input" type="text" placeholder="Exercise Name" />
</div>
<div>
<Field name="sets" ponent="input" type="number" />
<label htmlFor="sets"> sets</label>
</div>
<div>
<Field name="reps" ponent="input" type="number" />
<label htmlFor="reps"> reps</label>
</div>
<div>
<Field name="lbs" ponent="input" type="number" />
<label htmlFor="lbs"> lbs</label>
</div>
<button type="submit">Submit</button>
</form>
)
ExercisesForm = reduxForm({
form: 'exercise'
})(ExercisesForm)
const mapStateToProps = state => ({
uid: state.auth.uid,
});
export default connect(
mapStateToProps,
undefined
)(ExercisesForm);
I am writing a React/Redux app that uses Firebase Auth/Firestore to keep track of a user's gym exercises. I have Redux Form to handle data submission and I have the below example data structure I want to achieve in Firestore:
users {
id {
name: 'John Smith'
uid: 'k1s7fxo9oe2ls9u' (es from Firebase Auth)
exercises: {
{
name: 'Bench Press',
sets: 3,
reps: 10,
lbs: 100,
}
}
}
}
However, I can't figure out how to keep adding new exercise objects to the exercises subcollection (in Firestore I guess it would be a field type of map). What I want to do is have new objects in "exercises" as the user submits new forms. So for example, if the user wanted to add a Deadlift exercise, it would look like the below:
users {
id {
name: 'John Smith'
uid: 'k1s7fxo9oe2ls9u' (es from Firebase Auth)
exercises: {
{
name: 'Bench Press',
sets: 3,
reps: 10,
lbs: 100,
},
{
name: 'Deadlift',
sets: 3,
reps: 12,
lbs: 120,
}
}
}
}
Calling db.collection('users').doc(doc.id).add({"exercises": values});
just updates the Bench Press object that's there already rather than adding a new one on submission of the form.
But calling db.collection('users').doc(doc.id).add({"exercises": values});
gives me this error: Uncaught (in promise) TypeError: _firebase__WEBPACK_IMPORTED_MODULE_3__.default.collection(...).doc(...).add is not a function.
I've been struggling with this for quite a while, any help is hugely appreciated.
This is my ponent:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Field, reduxForm } from 'redux-form';
import db from '../../../firebase';
import '@firebase/firestore';
import { store } from '../../../App';
const formSubmit = (values)=> {
const currentUserId = store.getState().auth.uid;
db.collection("users").get().then((usersSnapshot) => {
usersSnapshot.forEach((doc) => {
// looking for the current user and then updating their data
if(doc.data().uid === currentUserId) {
db.collection('users').doc(doc.id).add({
"exercises": values,
});
}
});
});
}
let ExercisesForm = ({ handleSubmit }) => (
<form onSubmit={handleSubmit(formSubmit)}>
<div>
<Field name="name" ponent="input" type="text" placeholder="Exercise Name" />
</div>
<div>
<Field name="sets" ponent="input" type="number" />
<label htmlFor="sets"> sets</label>
</div>
<div>
<Field name="reps" ponent="input" type="number" />
<label htmlFor="reps"> reps</label>
</div>
<div>
<Field name="lbs" ponent="input" type="number" />
<label htmlFor="lbs"> lbs</label>
</div>
<button type="submit">Submit</button>
</form>
)
ExercisesForm = reduxForm({
form: 'exercise'
})(ExercisesForm)
const mapStateToProps = state => ({
uid: state.auth.uid,
});
export default connect(
mapStateToProps,
undefined
)(ExercisesForm);
Share
Improve this question
edited Dec 30, 2018 at 23:50
evsc
asked Dec 30, 2018 at 15:31
evscevsc
972 silver badges8 bronze badges
3
- I don't understand. Is exercises really a subcollection, or just an array field on the user doc? Those are different things. Please be clear about how you're organizing your data. – Doug Stevenson Commented Dec 30, 2018 at 17:27
- Sorry for the confusion, it's meant to be a subcollection. As the user pletes the form, a new object is to be added to it, so for example if the user wanted to add a deadlift exercise, the data then looks like this: users { id { name: 'John Smith' uid: 'k1s7fxo9oe2ls9u' (es from Firebase Auth) exercises: { { name: 'Bench Press', sets: 3, reps: 10, lbs: 100, }, { name: 'Deadlift', sets: 3, reps: 10, lbs: 150, } } } } – evsc Commented Dec 30, 2018 at 23:21
- I've edited the question so that the example I gave could be formatted. Thank you! – evsc Commented Dec 30, 2018 at 23:31
2 Answers
Reset to default 5You should be able to say:
db
.collection('users')
.doc(doc.id)
.collection('exercises')
.add(values);
Where values
contains all the fields of the document you want to add. It will create a new document with a random id in the exercises subcollection.
So this won't work in the latest version of Firebase V9.
So below is how I added a subcollection to a document in the latest version:
const docRef = doc(database, "userDocs", session.user.email);
const colRef = collection(docRef, "docs");
await addDoc(colRef, {
fileName: input,
timestamp: serverTimestamp(),
})
.then(() => {
console.log("CREATED");
})
.catch((err) => {
console.error("Error creating document", err);
});
This will created a structure like
userDocs
-> userEmail
-> docs
-> uid
-> data
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745139053a4613343.html
评论列表(0条)