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 now 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
CodePudding user response:
The onAuthStateChanged()
observer runs every time the user's auth state changes and then the set()
will overwrite the existing document removing any existing data. You can try using merge
option that won't delete rest of the fields as shown below:
const docRef = doc(db, 'users', user.uid)
await setDoc(docRef, { food, quantity }, { merge: true })
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 use updateDoc
thereafter.
Alternatively, you can also unsubscribe from the listener as shown below:
const handleSubmit = async (e) => {
e.preventDefault();
const unsub = onAuthStateChanged(auth, async (user) => {
// process data
unsub();
})
}
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:
const user = auth.currentUser;
if (user) {
// update document.
}
CodePudding user response:
If you want to create-or-update the document, you can use { merge: true }
:
await setDoc(doc(collectionRef, uid), {
food: food,
quantity: quantity,
}, { merge: true }) //