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

Dialogflow聊天机器人使用Firestore自动ID写入数据报错排查

Dialogflow Firestore 自动ID写入报错问题解决

我在基于Dialogflow开发聊天机器人,采用Firestore作为数据库。原本使用自定义自动ID生成器,现尝试改用Firestore内置自动ID生成器,修改代码后虽能成功写入数据,但触发报错。

原代码

function AddWaterConsumption (agent) {
  // Get parameter from Dialogflow with the string to add to the database
  var databaseEntry = { 
      "PatientID": agent.parameters.Patient_ID,
      "DailyConsumption": agent.parameters.Water_consumption_user,
      "DailyWaterPlan": agent.parameters.Daily_water_plan,
  };
  let Patient_ID = agent.parameters.Patient_ID;
  console.log(`Okay, we're trying to write to database: ${databaseEntry}`);
  
  // here is where changes are needed
  const dialogflowAgentRef = db.collection("WaterConsumption").doc(genRand(8)); // need to change to add()    
  console.log(`Found agent ref: ${dialogflowAgentRef}`);
  return db.runTransaction(t => {
    t.set(dialogflowAgentRef, databaseEntry); // this will also need to be changed
    return Promise.resolve('Write complete');
 
  }).then(doc => {
    agent.add(`I have updated your daily water consumption`); 
    agent.add(`Is anything else I can do for you?.`);
  }).catch(err => {
    console.log(`Error writing to Firestore: ${err}`);
    agent.add(`Failed to write "${dialogflowAgentRef}" to the Firestore database.`);
  });
}

修改后的关键代码

console.log(`Okay, we're trying to write to database: ${databaseEntry}`);
const dialogflowAgentRef = db.collection("WaterConsumption"); // changed here
console.log(`Found agent ref: ${dialogflowAgentRef}`);
return db.runTransaction(t => {
  t.set(db.collection("WaterConsumption").add(databaseEntry), databaseEntry); // and here

报错信息

Argument "documentRef" is not a valid DocumentReference. Input is not a plain JavaScript object
中文翻译:参数"documentRef"不是有效的DocumentReference。输入不是纯JavaScript对象

问题原因与解决方案

问题出在修改后的事务代码:t.set(db.collection("WaterConsumption").add(databaseEntry), databaseEntry)。Firestore的add()方法返回的是一个Promise对象,而非DocumentReference,直接将其传给t.set()的第一个参数会触发类型错误——因为t.set()要求第一个参数必须是有效的DocumentReference实例。

在事务中使用Firestore内置自动ID的正确方式是:先创建一个不带参数的doc()引用(Firestore会自动生成唯一ID),再在事务中调用set()写入数据。

正确修改后的代码片段

console.log(`Okay, we're trying to write to database: ${databaseEntry}`);
// 创建带自动ID的文档引用
const dialogflowAgentRef = db.collection("WaterConsumption").doc(); 
console.log(`Found agent ref: ${dialogflowAgentRef}`);
return db.runTransaction(t => {
  t.set(dialogflowAgentRef, databaseEntry); // 使用生成的引用执行set操作
  return Promise.resolve('Write complete');
})
// 后续的then和catch逻辑保持原代码不变

说明

  • db.collection("WaterConsumption").doc()不带参数调用时,Firestore会自动生成一个唯一ID的DocumentReference,这就是官方推荐的内置自动ID生成方式。
  • 事务中必须使用明确的DocumentReference来执行写入操作,不能直接使用add()——因为add()本质是doc().set()的语法糖,但在事务上下文里需要显式创建引用才能保证事务的原子性。
  • 此修改既实现了Firestore自动ID的需求,又修复了类型错误,同时保留了原有的事务逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 09:45:40