如何修改Firestore操作使数组支持重复元素添加?
问题
在Firestore中向同一数组添加相同数据时,不会新增重复元素。我希望输入相同数据时,数组能存入重复元素(生成多个数组索引)。
- 当前效果:数组中相同元素只会保留一个,比如多次添加“Push Ups”后,数组里仅有一个该元素
- 预期效果:数组中允许重复元素,比如多次添加“Push Ups”后,数组里会出现多个该元素,每个占据独立的数组索引
当前使用代码如下:
// collection reference const collectionRef = collection(db, 'exercises data'); // submit function to add the exercises data const handleSubmit = async (e) => { e.preventDefault(); const usr = auth.currentUser; await setDoc(doc(collectionRef, usr.uid), { exercise: arrayUnion(exercise), sets: arrayUnion(Number(sets)), reps: arrayUnion(Number(reps)), }, { merge: true }) }
解决方案
问题根源在于你用了arrayUnion()——Firestore的这个API设计初衷就是向数组添加不重复元素,当元素已存在时会自动忽略,所以要存重复元素不能用它。
换个思路:先读取当前文档里的数组,手动把新元素推进去,再写回Firestore。修改后的代码如下:
// collection reference const collectionRef = collection(db, 'exercises data'); // submit function to add the exercises data const handleSubmit = async (e) => { e.preventDefault(); const usr = auth.currentUser; const docRef = doc(collectionRef, usr.uid); // 获取当前文档数据 const docSnap = await getDoc(docRef); // 初始化数组,文档不存在时用空数组兜底 let currentExercises = docSnap.exists() ? (docSnap.data().exercise || []) : []; let currentSets = docSnap.exists() ? (docSnap.data().sets || []) : []; let currentReps = docSnap.exists() ? (docSnap.data().reps || []) : []; // 手动添加新元素(允许重复) currentExercises.push(exercise); currentSets.push(Number(sets)); currentReps.push(Number(reps)); // 更新文档 await setDoc(docRef, { exercise: currentExercises, sets: currentSets, reps: currentReps, }, { merge: true }) }
补充说明
- 这种先读后写的方式,单用户场景下完全够用;如果是多用户并发修改同一个数组,建议用Firestore事务包裹读写操作,避免数据覆盖。
- 代码里做了兜底处理:如果文档还没创建,会自动初始化空数组并添加第一个元素。
内容的提问来源于stack exchange,提问作者Ashka
相关产品推荐
相关产品推荐

