Firebase 更新物联网设备配置时出现谷歌云功能错误(权限被拒绝)
所以,我需要做的基本上是,当我在Google Cloud Firestore中更改一个值时,它会触发一个云函数将该值发送到IoT设备。以下是我所做的:Firebase 更新物联网设备配置时出现谷歌云功能错误(权限被拒绝),firebase,google-cloud-firestore,google-cloud-functions,Firebase,Google Cloud Firestore,Google Cloud Functions,所以,我需要做的基本上是,当我在Google Cloud Firestore中更改一个值时,它会触发一个云函数将该值发送到IoT设备。以下是我所做的: 我为此特定任务创建了一个服务帐户。我授予它以下权限: cloudiot.admin(用于管理谷歌云物联网设备) firebase.sdkAdminServiceAgent(用于管理Firestore) 所有者(临时所有者,用于调试) 我创建了一个物联网设备注册表,并在此注册表上创建了一个设备 创建了云函数,并将其服务帐户设置为我创建的帐户 以下
const functions=require(“firebase函数”);
const admin=require(“firebase管理员”);
const-iot=require(“@google-cloud/iot”);
const app=admin.initializeApp();
const firestore=app.firestore();
const client=new iot.v1.DeviceManager客户端();
设置({timestampsInSnapshots:true});
exports.deviceConfigs=functions.firestore
.document(“设备配置/{device}”)
.onWrite(异步(更改、上下文)=>{
const deviceId=context.params.device;
如果(!change.after.存在){
functions.logger.error(`deviceconfigurationremovedfor${deviceId}`);
返回;
}
const config=change.after.data();
const formattedName=client.devicePath(
process.env.GCLOUD_项目,
functions.config().iot.core.region,
functions.config().iot.core.registry,
设备ID
);
常量请求={
名称:formattedName,
binaryData:Buffer.from(JSON.stringify(config)).toString(“base64”),
};
等待client.modifyCloudToDeviceConfig(请求);
});
因此,每当我在集合“device configs”中的文档上写入时,就会触发该功能,并向IoT设备发送授权请求,通知配置更改。它是经过身份验证的,因为它直接从google后端运行,因为它是一个云功能,所以它应该作为我创建的服务帐户进行身份验证
但是,每次触发时,它都会在最后一行失败。以下是错误:
错误:7权限被拒绝:调用者在Object.onReceiveStatus(/workspace/node_modules/@grpc/grpc js/build/src/call.js:31:26)的Object.callerRomStatus(/workspace/node_modules/@grpc/grpc js/build/src/client.js:176:52)处没有权限(/workspace/node_modules/@grpc/grpc js/build/src/client interceptors.js:336:141)at Object.onReceiveStatus(/workspace/node_modules/@grpc/grpc js/build/src/client interceptors.js:299:181)at/workspace/node_modules/@grpc/grpc js/build/src/call stream.js:145:78 at process和拒绝(内部/进程/任务队列:79:11)
我真的不知道该怎么办了。我曾尝试在模拟器上本地运行它,使用服务密钥作为身份验证,但它仍然返回相同的错误。我试图找到一种方法来记录Google Cloud接收到的所有api请求,以查看头上是否存在身份验证,但我找不到这样做的方法
编辑
好的,我不知道这是否有帮助,但我还有另一个云功能,可以侦听PubSub主题上的新消息,并相应地更新Firestore数据库。该功能工作正常。代码如下:
const functions=require(“firebase函数”);
const admin=require(“firebase管理员”);
const-iot=require(“@google-cloud/iot”);
const app=admin.initializeApp();
const firestore=app.firestore();
const client=new iot.v1.DeviceManager客户端();
设置({timestampsInSnapshots:true});
exports.deviceState=functions.pubsub
.主题(“设备事件”)
.onPublish(异步(消息)=>{
functions.logger.warn(“mensage:,{message});
const deviceId=message.attributes.deviceId;
const deviceRef=firestore.doc(`device state/${deviceId}`);
试一试{
等待设备更新({
状态:message.json,
在线:没错,
});
functions.logger.log(“设备更新成功”);
}捕获(错误){
函数.logger.error(错误);
}
});
const-app=admin.initializeApp()
将此更改为
const serviceAccount = require("./serviceAccountKey.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://YOURPROJECTNAME.firebaseio.com"
});
从firebase下载ServiceAccountKey并将其添加到该文件所在的同一文件夹中,然后添加数据库url确定,找到解决方案!
基本上,请确保三四次检查项目和注册表名称!逐个字符检查。这件事花了我尴尬的4天时间才解决。谢谢Tasnuva。因为我没有使用实时数据库,所以我没有指定数据库URL。它返回了相同的错误在firebase帐户中创建firestore DB并添加您的项目t name确保firebase帐户中的firestore规则是读写真实的相同错误。我认为问题不在于firestore,因为我可以在数据库上很好地读写。我认为问题在于云功能和物联网核心之间。你是否从云启用谷歌云计算?你有默认的服务帐户吗?很好