Ошибка invalid_grant при отправке команды на устройство

Я копирую и вставляю код сюда, и проблем с компиляцией нет https://cloud.google.com/iot/docs/how-tos/commands#iot-core-send-command-nodejs

Но это не удалось с ошибкой «invalid_grant».

Сначала я установил google-cloud/iot и использую последнюю поддерживаемую версию:

npm i @google-cloud/iot -- хорошо

версия нпм: 6.4.1

Версия node.jo: v8.13.0

версия firebase: 6.11.0

вин10 про

Если я запускаю команду 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' }

person Jorge Montalvão    schedule 07.06.2019    source источник


Ответы (2)


Некоторые пакеты «google-cloud» не поддерживаются на локальном хосте.

Например, триггеры PubSub:

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

это генерирует сообщение ниже:

Игнорирование триггера "имя_функции", поскольку служба "pubsub.googleapis.com" еще не поддерживается.

Кроме того, я добавил зависимости от google-cloud в package.json, и он хорошо работает только в облаке.

  "dependencies": {
    "@google-cloud/iot": "^1.0.0",
    "@google-cloud/pubsub": "^0.28.0",
    "googleapis": "^40.0.0"
  }
person Jorge Montalvão    schedule 08.06.2019

Возможно, стоит попробовать более новую библиотеку, как описано в этом ответе:


  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);
    });
person class    schedule 11.06.2019