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

React应用中Firestore写入触发器无法更新stories_json文档排查

问题描述

在React应用中使用Firebase数据库,编写Firebase Cloud Functions函数,需求如下:

  • 当stories集合插入新文档时自动触发函数
  • 函数执行逻辑:
    1. 获取新文档的titleIt、titleEn、descriptionIt、descriptionEn属性
    2. 获取stories_json集合中指定文档(该文档初始包含空数组json)
    3. 将步骤1的属性组成对象推入数组
    4. 将更新后的数组写回stories_json的该文档

实际问题:每次向stories添加新文档,stories_json中的文档始终未更新,json数组保持为空。

以下是编写的函数代码:

exports.updateStoriesJson = functions.firestore
    .document("/stories/{storyId}")
    .onWrite(async (event) => {
      const storyData = event.after.data();
      if (storyData) {
        const titleIt = storyData.params.titleIt;
        const titleEn = storyData.params.titleEn;
        const descriptionIt = storyData.params.descriptionIt;
        const descriptionEn = storyData.params.descriptionEn;
        const json = {titleIt, titleEn, descriptionIt, descriptionEn};
        const jsdonDocCollection=admin.firestore().collection("stories_json");
        const jsonDoc=jsdonDocCollection.doc("7GaNrl34utwq7C9lvHz4");
        const docSnapshot = await firestore.get(jsonDoc);
        let jsonArray = docSnapshot.data().json;
        jsonArray.push(json);
        await jsonDoc.set({json: jsonArray});
      }
      return;
    });

stories_json集合结构:包含一个文档,该文档拥有空数组属性json。

错误分析与修复方案

主要错误点

  1. 文档属性获取方式错误:storyData是Firestore文档的直接数据对象,无需通过params访问属性,storyData.params本身不存在,导致所有属性变量为undefined,推入数组的是无效对象,甚至会引发后续执行错误。
  2. Firestore实例调用错误:代码中使用firestore.get(jsonDoc),但正确的调用方式是借助admin.firestore()实例(前提是已正确初始化admin模块),否则会因找不到firestore对象导致函数执行失败。
  3. 未处理文档不存在的情况:如果stories_json中的指定文档不存在,docSnapshot.data()会返回undefined,访问docSnapshot.data().json会直接抛出错误,导致函数中断,无法完成更新。
  4. 触发器选择不当:onWrite触发器会在文档创建、更新、删除时均触发,可能导致重复执行或不必要的操作,应该使用onCreate触发器,仅在新文档插入时触发。

修复后的代码

// 确保已初始化admin模块
const admin = require('firebase-admin');
admin.initializeApp();

exports.updateStoriesJson = functions.firestore
    .document("/stories/{storyId}")
    .onCreate(async (snap) => { // 使用onCreate触发器,仅处理新文档插入场景
      const storyData = snap.data();
      if (!storyData) return;

      // 直接从文档数据中获取目标属性
      const titleIt = storyData.titleIt;
      const titleEn = storyData.titleEn;
      const descriptionIt = storyData.descriptionIt;
      const descriptionEn = storyData.descriptionEn;
      const newItem = {titleIt, titleEn, descriptionIt, descriptionEn};

      const jsonDocRef = admin.firestore().collection("stories_json").doc("7GaNrl34utwq7C9lvHz4");
      const docSnapshot = await jsonDocRef.get();

      let jsonArray = [];
      // 处理文档存在/不存在的情况,避免报错
      if (docSnapshot.exists) {
        const docData = docSnapshot.data();
        jsonArray = docData.json || []; // 兼容json字段未定义的场景
      }

      jsonArray.push(newItem);
      // 使用merge: true,避免覆盖文档中可能存在的其他字段
      await jsonDocRef.set({json: jsonArray}, {merge: true});
    });

额外注意事项

  • 确保函数已正确部署:执行firebase deploy --only functions命令部署更新后的函数
  • 查看函数日志:通过Firebase控制台的「函数」页面查看执行日志,排查是否存在其他隐性错误
  • 原子性优化:若存在多文档同时插入的场景,建议使用Firebase事务(runTransaction)避免数组更新冲突

内容的提问来源于stack exchange,提问作者Yanitsa Halacheva

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 11:30:09