Google Cloud Functions向Firestore的map字段追加值出现覆盖如何解决
问题原因
- 你获取的
doc仅为Firestore文档引用对象,并没有拉取当前文档的实际内容,doc.Trainings为undefined,展开运算符没有生效,直接赋值新对象就会覆盖原有内容。 - 点路径更新用法错误:Firestore的
字段.子字段格式更新需要直接作为update方法的顶级key,不能嵌套在Trainings对象内部,嵌套写法会直接把带点的字符串作为map的key,而非识别为嵌套路径,这就是你实际运行结果中出现带点的异常key的原因。 - 原代码没有返回更新操作的Promise,云函数可能在写入操作完成前就被回收,容易出现异常。
修复后代码
exports.addTrainingtoList = functions.firestore .document('/users/{uid}/trainings/{trainings}') .onCreate((change, context) => { const doc = admin.firestore() .collection('users') .doc(context.params.uid) .collection('user') .doc('trainings'); const trainingsID = change.data().trainingsID; const trainingsName = change.data().training; const trainingsTimestamp = change.data().timestamp; // 直接使用带层级的点路径作为更新的顶级键,自动追加到Trainings map中 return doc.update({ [`Trainings.${trainingsID}.trainingsName`]: trainingsName, [`Trainings.${trainingsID}.trainingsDate`]: trainingsTimestamp, }).catch(err => { // 兼容处理:如果目标文档或Trainings字段不存在,用merge方式写入避免报错 if (err.code === 'not-found') { return doc.set({ Trainings: { [trainingsID]: { trainingsName: trainingsName, trainingsDate: trainingsTimestamp } } }, { merge: true }) } throw err; }) });
额外说明
如果要保证并发写入不会出现覆盖,还可以先读取当前文档的Trainings字段,合并新内容后再写入,普通场景下上述点路径更新的写法已经可以满足追加需求,且写入效率更高。
内容的提问来源于stack exchange,提问作者LazyTurtle
相关产品推荐
相关产品推荐

