Firestore技术问题:通过指定字段值获取文档ID并更新文档
问题:通过Firestore字段值查询文档ID并更新字段
我有一个名为users的Firestore集合,包含多个文档。需要通过文档中的email字段值获取对应文档的ID,并更新该文档的字段(登录用户不一定是目标用户)。
我尝试了以下代码:
firebaseConfig.auth().signInWithEmailAndPassword(email.value, password.value) .then(id => { if (id) { const data = { planid: 'WEB', } firebaseConfig .firestore() .collection('user') .where("email", "==", "email@email.com") .set(data, { merge: true }) .then(() => { console.log("Success") }); } }).catch(err => { console.log(err); });
控制台报错:
TypeError: config__WEBPACK_IMPORTED_MODULE_5_.default.firestore(...).collection(...).where(...).set is not a function
我知道指定文档ID可以完成更新(如下代码),但场景中无法预先知晓文档ID,需要通过邮箱地址查询获取:
firebaseConfig.auth().signInWithEmailAndPassword(email.value, password.value) .then(id => { if (id) { const data = { planid: 'WEB', } firebaseConfig .firestore() .collection('user') .doc("hcyfmskCVfbj77TwbXFLnJ20kH52") .set(data, { merge: true }) .then(() => { console.log("Success") }); } }).catch(err => { console.log(err); });
解决方案
原因
where()返回的是查询对象,而非单个文档引用,set()方法只能在文档引用上调用,因此直接链式调用会触发错误。必须先执行查询获取匹配的文档,再对文档进行更新。
修正代码
firebaseConfig.auth().signInWithEmailAndPassword(email.value, password.value) .then((userCredential) => { // signInWithEmailAndPassword返回的是userCredential,不是直接的id if (userCredential.user) { const data = { planid: 'WEB' }; firebaseConfig.firestore() // 注意:如果你的集合实际是users,改成collection('users') .collection('user') .where("email", "==", "email@email.com") .get() // 执行查询获取结果快照 .then((querySnapshot) => { // 遍历所有匹配的文档 querySnapshot.forEach((doc) => { doc.ref.set(data, { merge: true }) .then(() => console.log("文档更新成功")) .catch((err) => console.log("更新失败:", err)); }); if (querySnapshot.empty) { console.log("未找到匹配该邮箱的文档"); } }) .catch((err) => console.log("查询失败:", err)); } }) .catch(err => console.log("登录失败:", err));
补充提示
- 集合名检查:确认你的集合实际名称是
user还是users,代码中要保持一致 - 唯一邮箱场景:如果每个邮箱对应唯一文档,可以直接取第一个匹配项,无需遍历:
if (!querySnapshot.empty) { const targetDoc = querySnapshot.docs[0]; targetDoc.ref.set(data, { merge: true }) .then(() => console.log("更新成功")); } - 更新方式选择:可以用
update()替代set({merge: true}),update()仅更新指定字段,且文档不存在时会报错;set({merge: true})则会在文档不存在时自动创建。
内容的提问来源于stack exchange,提问作者Paul VI
相关产品推荐
相关产品推荐

