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
相关产品推荐
相关产品推荐

