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

Node.js中如何向数组追加对象?Firestore数组覆盖问题求助

解决Firestore数组被覆盖而非追加的问题

嘿,我仔细看了你的代码,发现问题根源在于每次收到请求时,你都重新初始化了一个空的converstations(哦对了,这里拼写应该是conversations)数组,然后只把当前的req.body推进去,接着用set({ merge: true })保存。但Firestore的merge选项对于数组的处理是替换而非追加——你传进去的新数组会直接覆盖掉旧的数组,自然就看不到之前的元素了。

要实现数组元素依次追加,你需要先从Firestore中读取现有的数组(如果存在的话),然后把新元素添加进去,再把更新后的数组存回去。具体步骤如下:

修正步骤

  1. 先尝试获取目标文档的快照,判断文档是否已经存在
  2. 如果文档存在,取出已有的conversation数组;如果不存在,初始化一个空数组
  3. 将当前的req.body(或者你需要的格式)推到数组里
  4. 最后用set或update保存更新后的数组

修改后的代码

app.post("/webhook", async (req, res) => {
  try {
    const phoneNumber = req.body.data.source;
    console.log(req.body.data.source);

    const profileSnapshot = await db
      .collection("Profiles")
      .where("phoneNumber", "==", `${phoneNumber}`)
      .get();

    if (profileSnapshot.docs.length === 1) {
      console.log('known')
    } else {
      console.log("unknown");
      
      // 1. 获取目标文档的引用
      const conversationDocRef = db
        .collection("WhatsappConversations")
        .doc(getISO8601Date())
        .collection("Conversations")
        .doc(phoneNumber);
      
      // 2. 获取文档快照,判断是否存在
      const conversationDocSnapshot = await conversationDocRef.get();
      let conversations = [];
      
      if (conversationDocSnapshot.exists) {
        // 如果文档存在,取出已有的conversation数组
        conversations = conversationDocSnapshot.data().conversation || [];
      }

      // 3. 根据条件添加当前请求内容到数组
      const messageText = req.body.data.content.text;
      if (messageText === "Hi" || messageText === "hi") {
        conversations.push(req.body); // 这里不需要JSON.stringify,Firestore可以直接存对象
      } else if (messageText === "1") {
        conversations.push(req.body);
        console.log("sending a link to the website for signup");
      } else if (messageText === "2") {
        conversations.push(req.body);
        console.log("Add contact /upload");
      }

      // 4. 保存更新后的数组,用merge确保其他字段(比如timestamp)也能正确更新
      await conversationDocRef.set(
        { 
          conversation: conversations, 
          timestamp: Date.now() 
        }, 
        { merge: true }
      );
    }
    res.sendStatus(200); // 别忘了给请求返回响应哦
  } catch (error) {
    console.error(error);
    res.sendStatus(500);
  }
})

额外说明

  • 我把JSON.stringify(req.body)改成了直接存req.body,因为Firestore支持直接存储JSON对象,这样后续读取数据会更方便,不需要再解析。如果你的业务场景确实需要字符串格式,可以改回去。
  • 记得给请求返回响应(res.sendStatus),否则客户端可能会因为超时报错。
  • 拼写错误converstations修正为conversations,避免后续维护时混淆。

内容的提问来源于stack exchange,提问作者lucifer luci

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 11:42:29