简体   繁体   English

在同一文档中添加新字段作为数组,而不使用 React 覆盖 Firestore 中的旧字段

[英]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 时,我才能添加更多字段

Firestore Firestore

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.

相关问题 如何使用本机反应将子集合添加到 firestore 中的文档 - How to add a sub collection to a document in firestore using react native 将包含整数类型字段的文档添加到 firestore - add a document which contains fields of type integers to firestore flutter firestore,在数组中添加新对象 - flutter firestore, add new object in array DynamoDB 在使用 TransactWrtieItems 时返回修改后的文档(旧的或新的) - DynamoDB return the modified document (Old or new) when using TransactWrtieItems 我想在特定日期将旧文档添加到新集合 - I want to add a old document to a new collection on a specific date 在 Firebase Cloud Firestore 中不覆盖的情况下在文档中添加更多字段 - Add more field in a document without overwrite in Firebase Cloud Firestore 是否可以在不在 Firestore 中添加文档的情况下将子集合添加到集合中? - Is it possible to add a subcollection to a collection without adding document in Firestore? Flutter Firestore:将数据列表添加到 Firestore 文档 - Flutter Firestore : Add a List of Data to Firestore Document 是否可以在 android 中不在 firestore 中创建文档的情况下将子集合添加到集合中? - Is it possible to add a sub collection to a collection without creating document in firestore in android? 如何使用 react-native 在 Firestore 中的嵌套数组上添加数据 - How to add data on nested array in Firestore with react-native
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM