[英]Add new fields as an array in the same document without override the old ones in Firestore using React
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:我正在尝试在与登录用户(相同 UID)相关的文档中添加新字段,以创建与用户 UID 具有相同 UID 的新文档,我使用以下内容:
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.我可以使用 updateDoc() function 添加更多字段,但如果我在创建新文档后不评论或删除 setDoc() function,它将覆盖文档中的字段。
screenshot of the DB (Firestore): I can add more fields only if I comment the setDoc() function after the doc first created数据库(Firestore)的屏幕截图:只有在首次创建文档后评论 setDoc() function 时,我才能添加更多字段
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.每次用户的身份验证 state 更改时都会运行
onAuthStateChanged()
观察器,然后set()
将覆盖现有文档并删除任何现有数据。 You can try using merge
option that won't delete rest of the fields as shown below:您可以尝试使用不会删除 rest 字段的
merge
选项,如下所示:
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.但是,这仍然会用您提供的新值覆盖“食物”和“数量”arrays。 So it might be best to use
setDoc()
only once after users registers in your application and use updateDoc
thereafter.因此,最好只在用户在您的应用程序中注册后使用
setDoc()
一次,然后再使用updateDoc
。
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.如果 auth state 在您的处理完成之前更改,处理程序可能仍会再次触发。 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:您应该在 web 应用程序首次加载时使用
onAuthStateChanged()
,然后根据用户的身份验证 state 将用户重定向到不同的页面。确认用户已登录后,您可以简单地使用以下命令获取当前用户:
const user = auth.currentUser;
if (user) {
// update document.
}
If you want to create-or-update the document, you can use { merge: true }
:如果要创建或更新文档,可以使用
{ merge: true }
:
await setDoc(doc(collectionRef, uid), {
food: food,
quantity: quantity,
}, { merge: true }) // 👈
Also see the second code snippet in the documentation on setting a documents .另请参阅有关设置文档的文档中的第二个代码片段。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.