如何在Firebase中避免重复添加已存在的Coin至coins集合?
嘿,这个问题我之前也碰到过,其实核心就是要先确认用户有没有已经关注过这个币种,再决定要不要往数据库里加~ 你现在每次点击都用doc()生成新的随机文档ID,哪怕是同一个币种同一个用户,也会重复创建记录,咱们来改改逻辑:
解决思路:先检查再操作
我们需要把点击处理函数改成异步的,先查询数据库里是否存在当前用户关注该币种的记录,再分情况执行添加/删除(毕竟按钮应该是「关注/取消关注」的切换逻辑对吧?)
方案1:用查询判断是否已存在
const handleClick = async () => { const currentUser = firebase.auth().currentUser; // 先处理用户未登录的情况,避免报错 if (!currentUser) { alert('请先登录后再进行关注操作'); return; } const userId = currentUser.uid; // 查询当前用户是否已关注该币种 const querySnapshot = await db.collection("coins") .where("userId", "==", userId) .where("id", "==", price.id) .get(); if (!following) { // 当前未关注:如果没有记录才添加 if (querySnapshot.empty) { const data = { following: true, logo_url: price.logo_url, id: price.id, name: price.name, price: price.price, userId: userId }; await db.collection("coins").add(data); } // 更新按钮状态 setTitle("Following"); setFollowing(true); } else { // 当前已关注:删除对应的记录 if (!querySnapshot.empty) { querySnapshot.forEach(doc => doc.ref.delete()); } setTitle("Follow"); setFollowing(false); } };
方案2:用自定义文档ID(更高效)
上面的查询方案需要每次点击都查数据库,更高效的方式是用「用户ID+币种ID」作为文档的唯一ID,这样直接通过文档ID就能判断是否存在,不用走查询:
const handleClick = async () => { const currentUser = firebase.auth().currentUser; if (!currentUser) { alert('请先登录后再进行关注操作'); return; } const userId = currentUser.uid; // 生成唯一文档ID,确保同一用户同一币种只会有一条记录 const docId = `${userId}_${price.id}`; const docRef = db.collection("coins").doc(docId); if (!following) { const docSnapshot = await docRef.get(); // 只有当文档不存在时才添加 if (!docSnapshot.exists) { const data = { following: true, logo_url: price.logo_url, id: price.id, name: price.name, price: price.price, userId: userId }; await docRef.set(data); } setTitle("Following"); setFollowing(true); } else { // 已关注就删除文档 await docRef.delete(); setTitle("Follow"); setFollowing(false); } };
额外小提示
如果用方案1的查询逻辑,记得去Firestore控制台给coins集合创建复合索引(userId和id的组合索引),这样查询速度会更快哦~
内容的提问来源于stack exchange,提问作者Will
相关产品推荐
相关产品推荐

