Estoy tratando de agregar nuevos campos en un documento relacionado con el usuario que inició sesión (mismo UID) para crear un nuevo documento con el mismo UID que el UID del usuario, uso lo siguiente:
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}`)
}
}, [])
}
Para agregar más campos a la matriz, uso lo siguiente:
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}`)
}
}, [])
}
el codigo completo:
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}`)
}
}, [])
}
Puedo agregar más campos con la función updateDoc(), pero si no comento o elimino la función setDoc() después de crear el nuevo documento, anulará los campos dentro del documento.
captura de pantalla de la base de datos (Firestore): Puedo agregar más campos solo si comento la función setDoc() después de que se creó el documento por primera vez
El observador onAuthStateChanged() se ejecuta cada vez que cambia el estado de autenticación del usuario y luego set() sobrescribirá el documento existente eliminando cualquier dato existente. Puede intentar usar la opción de merge que no eliminará el resto de los campos como se muestra a continuación:
const docRef = doc(db, 'users', user.uid)
await setDoc(docRef, { food, quantity }, { merge: true })
Sin embargo, esto aún sobrescribirá las matrices de 'comida' y 'cantidad' con el nuevo valor que proporcione. Por lo tanto, podría ser mejor usar setDoc() solo una vez después de que los usuarios se registren en su aplicación y luego use updateDoc .
Alternativamente, también puede darse de baja del oyente como se muestra a continuación:
const handleSubmit = async (e) => {
e.preventDefault();
const unsub = onAuthStateChanged(auth, async (user) => {
// process data
unsub();
})
}
El controlador aún podría activarse nuevamente si el estado de autenticación cambia antes de que se complete el procesamiento. Debe usar onAuthStateChanged() cuando la aplicación web se carga por primera vez y luego redirigir al usuario a diferentes páginas según su estado de autenticación. Una vez que confirme que el usuario ha iniciado sesión, simplemente puede usar lo siguiente para obtener el usuario actual:
const user = auth.currentUser;
if (user) {
// update document.
}
Si desea crear o actualizar el documento, puede usar { merge: true } :
await setDoc(doc(collectionRef, uid), {
food: food,
quantity: quantity,
}, { merge: true }) // 👈
Consulte también el segundo fragmento de código en la documentación sobre cómo configurar un archivo documents .