Cloud Function无法获取Google Cloud IoT Pub/Sub主题数据并存入Firestore数据库
问题核心原因
Firestore 的 update() 方法仅允许更新已经存在的文档,你日志中返回的NOT_FOUND: No document to update错误正是因为device-configs/aquast1-dev文档尚未提前创建,update()不会自动生成缺失的文档,因此执行失败。
解决方案
方案1:支持自动创建未注册设备的文档(符合你预期的自动生成数据库的需求)
将你代码中的update()调用替换为支持「文档不存在则自动创建、存在则更新指定字段」的set()方法,附加{merge: true}参数即可,修改后的核心代码如下:
exports.deviceState = functions.pubsub.topic('sensors').onPublish(async (message) => { const deviceId = message.attributes.deviceId; const deviceRef = firestore.doc(`device-configs/${deviceId}`); try { // 替换update为set,添加merge: true参数 await deviceRef.set({ 'state': message.json, 'online': true, 'timestamp' : admin.firestore.Timestamp.now() }, { merge: true }); console.log(`State updated for ${deviceId}`); } catch (error) { console.error(`${deviceId}状态更新失败`, error); } });
参数说明:
- 直接调用
set(数据)无附加参数:若文档不存在会新建,若文档已存在会直接覆盖全部内容 - 附加
{merge: true}参数:仅更新传入的字段,保留文档原有其他字段,行为和原update()完全一致,同时兼容文档不存在的场景,会自动创建缺失的文档
方案2:保留「设备必须先注册才能上报」的业务逻辑
如果你的业务要求必须先手动注册设备才能上报状态,不需要自动创建设备文档,直接在Firestore控制台的device-configs集合下提前创建对应deviceId的文档即可解决报错。
其他可选检查项
- 确认你已在Firebase控制台完成Firestore数据库的初始化,选择了对应存储区域
- 若你手动修改过项目IAM权限,可确认Cloud Function默认服务账号(格式为
你的项目ID@appspot.gserviceaccount.com)拥有Firestore写入权限,默认配置下该权限是自动开通的
内容的提问来源于stack exchange,提问作者Gabriel Robledo Ahumada
相关产品推荐
相关产品推荐

