You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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));

补充提示

  1. 集合名检查:确认你的集合实际名称是user还是users,代码中要保持一致
  2. 唯一邮箱场景:如果每个邮箱对应唯一文档,可以直接取第一个匹配项,无需遍历:
    if (!querySnapshot.empty) {
      const targetDoc = querySnapshot.docs[0];
      targetDoc.ref.set(data, { merge: true })
        .then(() => console.log("更新成功"));
    }
    
  3. 更新方式选择:可以用update()替代set({merge: true}),update()仅更新指定字段,且文档不存在时会报错;set({merge: true})则会在文档不存在时自动创建。

内容的提问来源于stack exchange,提问作者Paul VI

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 06:13:17