向设备发送命令时发生错误invalid_grant

时间:2019-06-07 10:58:07

标签: firebase google-cloud-functions google-cloud-iot

我正在此处复制和粘贴代码,没有编译问题 https://cloud.google.com/iot/docs/how-tos/commands#iot-core-send-command-nodejs

但是失败,并显示错误“ invalid_grant”。

首先,我安装了google-cloud / iot,并且使用的是最新支持的版本:

npm i @ google-cloud / iot-好的

npm版本:6.4.1

node.jo版本:v8.13.0

firebase版本:6.11.0

win10专业版

如果我运行gcloud命令,效果很好

gcloud iot devices commands send \
    --command-data="Hello device" \
    --region=us-central1  \
    --registry=device001-registry \
    --device=device001-dev

这是代码。我刚刚从样本中获得了所需的东西。 我不确定是否错过了一些部署前的步骤。

const functions = require('firebase-functions');
const admin     = require('firebase-admin');
admin.initializeApp()

exports.sendCommandToDevice = functions.https.onRequest((request, response) => {
//Source https://cloud.google.com/iot/docs/how-tos/commands#iot-core-send-command-nodejs
//npm i @google-cloud/iot
    const iot            = require('@google-cloud/iot');
    const client         = new iot.v1.DeviceManagerClient();
    const cloudRegion    = 'us-central1';
    const projectId      = 'test01';             // 'adjective-noun-123';
    const deviceId       = 'device001-dev';      // 'my-device';
    const registryId     = 'device001-registry'; // 'my-registry';
    const commandMessage = 'Hello device';
    const binaryData     = Buffer.from(commandMessage).toString('base64');

    const formattedName = client.devicePath(
        projectId,
        cloudRegion,
        registryId,
        deviceId
    );

    // NOTE: The device must be subscribed to the wildcard subfolder
    // or you should specify a subfolder.
    const devRequest = {
        name: formattedName,
        binaryData: binaryData,
        //subfolder: <your-subfolder>
    };

    client
        .sendCommandToDevice(devRequest)
        .then(() => {
            console.log('Sent command ok!');
        })
        .catch(err => {
            console.error(err);
        });
    response.send("Sent command done");
});

日志输出为

i  functions: Finished "sendCommandToDevice" in ~1s
>  { Error: Getting metadata from plugin failed with error: invalid_grant
>      at Http2CallStream.call.on (D:\Jorge\test01\node_modules\
>      at emitOne (events.js:121:20)
>      at Http2CallStream.emit (events.js:211:7)
>      at Http2CallStream.endCall (D:\Jorge\test01\node_modules\
>      at D:\Jorge\test01\node_modules\@grpc\grpc-js\build\src\c
>      at <anonymous>
>      at process._tickCallback (internal/process/next_tick.js:189:7)
>    code: '400',
>    details: 'Getting metadata from plugin failed with error: invalid_grant',
>    metadata: Metadata { options: undefined, internalRepr: Map {} },
>    note: 'Exception occurred in retry method that was not classified as transient' }

2 个答案:

答案 0 :(得分:0)

本地主机不支持某些“ google-cloud”软件包。

例如,PubSub触发器:

export.<function_name> = 
  functions.pubsub.topic('<topic_name>').onPublish((message, context) => {})

这将产生以下消息:

  

由于不支持服务“ pubsub.googleapis.com”,因此忽略触发器“ function_name”。

此外,我在package.json中添加了google-cloud依赖关系,并且它仅在云中有效

  "dependencies": {
    "@google-cloud/iot": "^1.0.0",
    "@google-cloud/pubsub": "^0.28.0",
    "googleapis": "^40.0.0"
  }

答案 1 :(得分:0)

可能值得尝试使用in this answer中所述的更新的库:


  const iot = require('@google-cloud/iot');

  const newclient = new iot.v1.DeviceManagerClient({
    // optional auth parameters.
  });

  const parentName = `projects/${projectId}/locations/${cloudRegion}`;
  const registryName = `${parentName}/registries/${registryId}`;
  const binaryData = Buffer.from(data).toString('base64');
  const request = {
    name: `${registryName}/devices/${deviceId}`,
    binaryData: binaryData,
  };
  newclient.modifyCloudToDeviceConfig(request)
    .then(responses => {
      const response = responses[0];
      // doThingsWith(response)
    })
    .catch(err => {
      console.error(err);
    });