I’m trying to add new fields in a document that related to the logged in user (same UID)
to create a new document with the same UID as the user’s UID I use the following:
const collectionRef = collection(db, 'data');
// submit function to add data
const handleSubmit = async (e) => {
e.preventDefault();
onAuthStateChanged(auth, async (user) => {
const uid = user.uid;
try {
// overrides the data
await setDoc(doc(collectionRef, uid), {
food: food,
quantity: quantity,
})
alert("Data added successfully")
} catch (error) {
alert(`Data was not added, ${error.message}`)
}
}, [])
}
For add more fields to the array, I use the following:
const collectionRef = collection(db, 'data');
// submit function to add data
const handleSubmit = async (e) => {
e.preventDefault();
onAuthStateChanged(auth, async (user) => {
const uid = user.uid;
try {
await updateDoc(doc(collectionRef, uid), {
food: arrayUnion(food),
quantity: arrayUnion(quantity),
})
alert("Data added successfully")
} catch (error) {
alert(`Data was now added, ${error.message}`)
}
}, [])
}
the complete code:
const collectionRef = collection(db, 'data');
const handleSubmit = async (e) => {
e.preventDefault();
onAuthStateChanged(auth, async (user) => {
const uid = user.uid;
try {
// overrides the data - ???
await setDoc(doc(collectionRef, uid), {
food: food,
quantity: quantity,
})
// add more fields to the array
await updateDoc(doc(collectionRef, uid), {
food: arrayUnion(food),
quantity: arrayUnion(quantity),
})
alert("Data added successfully")
} catch (error) {
alert(`Data was now added, ${error.message}`)
}
}, [])
}
I can add more fields with the updateDoc() function, but if I will not comment or delete the setDoc() function after creating the new document, it will override the fields inside the document.
screenshot of the DB (Firestore):
I can add more fields only if I comment the setDoc() function after the doc first created
2
Answers
The
onAuthStateChanged()
observer runs every time the user’s auth state changes and then theset()
will overwrite the existing document removing any existing data. You can try usingmerge
option that won’t delete rest of the fields as shown below:This will still however overwrite the ‘food’ and ‘quantity’ arrays with the new value that you provide. So it might be best to use
setDoc()
only once after users registers in your application and useupdateDoc
thereafter.Alternatively, you can also unsubscribe from the listener as shown below:
The handler might still trigger again if auth state changes before your processing is complete. You should use
onAuthStateChanged()
when the web app loads for the first time and then redirect user to different pages based on their auth state. Once you confirm that user is logged in then you can simply use the following to get current user:If you want to create-or-update the document, you can use
{ merge: true }
:Also see the second code snippet in the documentation on setting a documents.