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

React中如何在Firebase的runTransaction内创建新文档引用?

在Firestore事务中创建新文档的正确方式

你当前代码的问题在于:用collection()获取的是集合引用,但transaction.set()需要传入的是具体的文档引用,这会导致执行报错。以下是两种正确创建新文档引用的方案:

方案1:自动生成文档ID

通过doc()函数传入集合引用,Firebase会自动生成唯一的文档ID:

const initailizeData = async () => {
  setIsLoading(true);
  // 先判断用户是否登录
  if (!auth.currentUser) {
    alert("请先登录");
    setIsLoading(false);
    return;
  }
  try {
    await runTransaction(db, async (transaction) => {
      // 获取用户的record集合引用
      const recordsCollection = collection(db, "users", auth.currentUser.uid, "record");
      // 创建自动生成ID的新文档引用
      const newRecordRef = doc(recordsCollection);
      // 事务中设置文档数据
      transaction.set(newRecordRef, {
        amount: 1000,
        createdAt: new Date()
      });
    });
  } catch (err) {
    alert(err.message || "创建记录失败");
  } finally {
    setIsLoading(false);
  }
};

方案2:自定义文档ID

如果需要自己指定文档ID,直接将ID作为doc()的最后一个参数:

const initailizeData = async () => {
  setIsLoading(true);
  if (!auth.currentUser) {
    alert("请先登录");
    setIsLoading(false);
    return;
  }
  try {
    await runTransaction(db, async (transaction) => {
      // 自定义文档ID(示例:用时间戳)
      const customDocId = `record_${Date.now()}`;
      // 创建指定ID的文档引用
      const newRecordRef = doc(db, "users", auth.currentUser.uid, "record", customDocId);
      transaction.set(newRecordRef, {
        amount: 1000,
        createdAt: new Date()
      });
    });
  } catch (err) {
    alert(err.message || "创建记录失败");
  } finally {
    setIsLoading(false);
  }
};

额外说明

  • 如果你的场景只是单纯创建新文档,不需要依赖其他文档的数据,其实可以直接使用addDoc()函数(无需事务),写法更简洁:
    await addDoc(collection(db, "users", auth.currentUser.uid, "record"), {
      amount: 1000,
      createdAt: new Date()
    });
    
  • 事务主要用于需要原子性读写的场景,比如创建新记录时需要先读取用户的总金额,再更新总金额和新增记录,这种情况下事务能保证操作的一致性。

内容的提问来源于stack exchange,提问作者Harsh Narwariya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 15:55:19