Ionic Vue Firestore查询:数据更新时如何避免条目重复?
你的思路是正确的,数据重复的核心原因是Firestore的onSnapshot实时监听器触发时会返回查询的全量最新数据,你没有清空旧数据就直接往数组里push,同时还存在重复注册监听器、家庭ID数组未清空的问题,完整修改方案如下:
存在的问题梳理
userHouseholdIds数组未在每次家庭集合监听器触发时清空,会持续累加历史家庭ID,重复查询旧家庭数据- 每次家庭集合监听器触发时,都会给对应家庭的entries集合新增一个重复的
onSnapshot监听器,同一条数据变动会触发多次回调 - entries监听器触发时直接往数组push全量数据,没有清空旧数据,导致内容重复
具体修改代码
首先调整数据结构,增加变量存储监听器实例方便销毁,避免重复注册:
data() { return { entries: [], entryUnsubscribeFns: [] // 存储所有entries集合的监听器销毁函数 }; },
然后修改beforeCreate里的逻辑:
beforeCreate: function () { auth.onAuthStateChanged((user) => { if (user) { const uid = user.uid; db.collection("households") .where("members", "array-contains", uid) .onSnapshot((snapshotChange) => { // 1. 先销毁之前注册的所有entries监听器,避免重复触发 this.entryUnsubscribeFns.forEach(unsubscribe => unsubscribe()) this.entryUnsubscribeFns = [] // 2. 清空旧的家庭ID和entries数据 const userHouseholdIds = [] this.entries = [] snapshotChange.forEach((doc) => { userHouseholdIds.push(doc.id); }); userHouseholdIds.forEach((householdId) => { db.collection("households") .doc(householdId) .get() .then((value) => { const householdId = value.id; const householdName = value.data().name; // 3. 存储当前entries监听器的销毁函数 const unsubscribeEntry = db.collection("households") .doc(householdId) .collection("entries") .onSnapshot((snapshotChange) => { // 4. 每次entries更新时先清空当前entries数组,再添加全量最新数据 this.entries = [] snapshotChange.forEach((doc) => { const newDoc = doc.data(); newDoc.id = doc.id; newDoc.householdName = householdName; newDoc.householdId = householdId; this.entries.push(newDoc); }); }); this.entryUnsubscribeFns.push(unsubscribeEntry) }); }); }); } }); }
补充优化点
如果需要避免每次清空整个数组的闪烁问题,可以判断snapshotChange.docChanges()的变动类型,只新增/修改/删除对应变动的条目,不需要全量替换。
内容的提问来源于stack exchange,提问作者Julian
相关产品推荐
相关产品推荐

