gRPC problem when adding devicekeys

Hi Guys,

I am trying to create a simple node.js program to create a device and its keys using the API via gRPC.

The device is created just fine as expected, but after the device is created it crashes with a “foreign key constraint” when creating the device keys.

Here is the program:

// Imports
const grpc = require(“@grpc/grpc-js”);
const device_grpc = require(“@chirpstack/chirpstack-api/api/device_grpc_pb”);
const device_pb = require(“@chirpstack/chirpstack-api/api/device_pb”);

//const deveui = ‘70b3557050000550’;
const deveui = ‘0000000000000001’;

// Create the client for the DeviceService.
const deviceService = new device_grpc.DeviceServiceClient(
“localhost:8080”,
grpc.credentials.createInsecure(),
);

// Create the Metadata object.
const metadata = new grpc.Metadata();
metadata.set(“authorization”, "Bearer " + “eyJ0eX…”);

let ChirpStackDevice = new device_pb.Device();
ChirpStackDevice.getTagsMap().set(‘meter_id’, ‘Nr. 123456’);
ChirpStackDevice.getTagsMap().set(‘area_id’, ‘14’);
ChirpStackDevice.getTagsMap().set(‘area’, ‘First Street’);
ChirpStackDevice.setDescription(‘Water Meter Nr. 123456 in Area “First Street” #14’);
ChirpStackDevice.setApplicationId( ‘e9ccf534-443d-42b0-8abf-9eae7ac42d26’ );
ChirpStackDevice.setDeviceProfileId( ‘6f4794d3-9c2a-40ea-a3ff-41197167210a’ );
ChirpStackDevice.setDevEui(deveui);
ChirpStackDevice.setName(‘API-test’);
ChirpStackDevice.setSkipFcntCheck(true);
ChirpStackDevice.setIsDisabled(false);

// Create Device Request
let ChirpStackCreateDeviceRequest = new device_pb.CreateDeviceRequest();
ChirpStackCreateDeviceRequest.setDevice(ChirpStackDevice);
deviceService.create( ChirpStackCreateDeviceRequest, metadata, (err, resp) => {
if (err !== null)
throw err;

// console.log("Device has been added with id: " + resp.getId());
console.log("Device has been added with resp: " + resp);
});

// Device
let ChirpStackDeviceKeys = new device_pb.DeviceKeys();
ChirpStackDeviceKeys.setDevEui(deveui);
ChirpStackDeviceKeys.setNwkKey(‘f534c9f04fa94a0abcb2420cf7516dad’);
ChirpStackDeviceKeys.setAppKey(‘000102030405060708090a0b0c0d0e0f’);

// Create DeviceKeys Request
let ChirpStackCreateDeviceKeysRequest = new device_pb.CreateDeviceKeysRequest();
ChirpStackCreateDeviceKeysRequest.setDeviceKeys(ChirpStackDeviceKeys);

deviceService.createKeys( ChirpStackCreateDeviceKeysRequest, metadata, (err, resp) => {
if (err !== null)
throw err;

    console.log("DeviceKeys has been added with id: " + resp);

})

  • and here is the error:

metedata: Metadata {
internalRepr: Map(1) {
‘authorization’ => [
‘Bearer eyJ0eX…’
]
},
options: {}
}
metedata: Metadata {
internalRepr: Map(1) {
‘authorization’ => [
‘Bearer eyJ0eX…’
]
},
options: {}
}
/home/kim/prog/adddev.js:54
throw err;
^

Error: 13 INTERNAL: insert or update on table “device_keys” violates foreign key constraint “device_keys_dev_eui_fkey”
at callErrorFromStatus (/home/kim/node_modules/@grpc/grpc-js/build/src/call.js:31:19)
at Object.onReceiveStatus (/home/kim/node_modules/@grpc/grpc-js/build/src/client.js:193:76)
at Object.onReceiveStatus (/home/kim/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:360:141)
at Object.onReceiveStatus (/home/kim/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:323:181)
at /home/kim/node_modules/@grpc/grpc-js/build/src/resolving-call.js:99:78
at process.processTicksAndRejections (node:internal/process/task_queues:77:11)
for call at
at ServiceClientImpl.makeUnaryRequest (/home/kim/node_modules/@grpc/grpc-js/build/src/client.js:161:32)
at ServiceClientImpl.createKeys (/home/kim/node_modules/@grpc/grpc-js/build/src/make-client.js:105:19)
at Object. (/home/kim/prog/adddev.js:52:15)
at Module._compile (node:internal/modules/cjs/loader:1254:14)
at Module._extensions…js (node:internal/modules/cjs/loader:1308:10)
at Module.load (node:internal/modules/cjs/loader:1117:32)
at Module._load (node:internal/modules/cjs/loader:958:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:23:47 {
code: 13,
details: ‘insert or update on table “device_keys” violates foreign key constraint “device_keys_dev_eui_fkey”’,
metadata: Metadata {
internalRepr: Map(3) {
‘content-type’ => [ ‘application/grpc’ ],
‘content-length’ => [ ‘0’ ],
‘date’ => [ ‘Fri, 12 Jan 2024 13:53:43 GMT’ ]
},
options: {}
}
}

Node.js v18.14.2

  • Now the interesting thing is that if I split the program in two parts like this:

Part1:

// Imports
const grpc = require(“@grpc/grpc-js”);
const device_grpc = require(“@chirpstack/chirpstack-api/api/device_grpc_pb”);
const device_pb = require(“@chirpstack/chirpstack-api/api/device_pb”);

//const deveui = ‘70b3557050000550’;
const deveui = ‘0000000000000001’;

// Create the client for the DeviceService.
const deviceService = new device_grpc.DeviceServiceClient(
“localhost:8080”,
grpc.credentials.createInsecure(),
);

// Create the Metadata object.
const metadata = new grpc.Metadata();
metadata.set(“authorization”, "Bearer " + “eyJ0eX…”);

let ChirpStackDevice = new device_pb.Device();
ChirpStackDevice.getTagsMap().set(‘meter_id’, ‘Nr. 123456’);
ChirpStackDevice.getTagsMap().set(‘area_id’, ‘14’);
ChirpStackDevice.getTagsMap().set(‘area’, ‘First Street’);
ChirpStackDevice.setDescription(‘Water Meter Nr. 123456 in Area “First Street” #14’);
ChirpStackDevice.setApplicationId( ‘e9ccf534-443d-42b0-8abf-9eae7ac42d26’ );
ChirpStackDevice.setDeviceProfileId( ‘6f4794d3-9c2a-40ea-a3ff-41197167210a’ );
ChirpStackDevice.setDevEui(deveui);
ChirpStackDevice.setName(‘API-test’);
ChirpStackDevice.setSkipFcntCheck(true);
ChirpStackDevice.setIsDisabled(false);

// Create Device Request
let ChirpStackCreateDeviceRequest = new device_pb.CreateDeviceRequest();
ChirpStackCreateDeviceRequest.setDevice(ChirpStackDevice);
deviceService.create( ChirpStackCreateDeviceRequest, metadata, (err, resp) => {
if (err !== null)
throw err;

// console.log("Device has been added with id: " + resp.getId());
console.log("Device has been added with resp: " + resp);
});

Part2:
// Imports
const grpc = require(“@grpc/grpc-js”);
const device_grpc = require(“@chirpstack/chirpstack-api/api/device_grpc_pb”);
const device_pb = require(“@chirpstack/chirpstack-api/api/device_pb”);

//const deveui = ‘70b3557050000550’;
const deveui = ‘0000000000000001’;

// Create the client for the DeviceService.
const deviceService = new device_grpc.DeviceServiceClient(
“localhost:8080”,
grpc.credentials.createInsecure(),
);

// Create the Metadata object.
const metadata = new grpc.Metadata();
metadata.set(“authorization”, "Bearer " + “eyJ0eX…”);

// DeviceKeys
let ChirpStackDeviceKeys = new device_pb.DeviceKeys();
ChirpStackDeviceKeys.setDevEui(deveui);
ChirpStackDeviceKeys.setNwkKey(‘f534c9f04fa94a0abcb2420cf7516dad’);
ChirpStackDeviceKeys.setAppKey(‘000102030405060708090a0b0c0d0e0f’);

// Create DeviceKeys Request
let ChirpStackCreateDeviceKeysRequest = new device_pb.CreateDeviceKeysRequest();
ChirpStackCreateDeviceKeysRequest.setDeviceKeys(ChirpStackDeviceKeys);

deviceService.createKeys( ChirpStackCreateDeviceKeysRequest, metadata, (err, resp) => {
if (err !== null)
throw err;

    console.log("DeviceKeys has been added with id: " + resp);

})

  • and then run the two parts one after the other it works like a breaze:

kim@freja ~/prog $ node part1.js; node part2.js
metedata: Metadata {
internalRepr: Map(1) {
‘authorization’ => [
‘Bearer eyJ0eX…’
]
},
options: {}
}
Device has been added with resp:
metedata: Metadata {
internalRepr: Map(1) {
‘authorization’ => [
‘Bearer eyJ0eX…’
]
},
options: {}
}
DeviceKeys has been added with id:

This tells me that the problem must be that the transaction is not committed in the database after the call to create the device.

There must be a way in the API to asure that the data is actually written and comitted in the database before I issue the call to create the devicekeys.

This is probably relatively simple, but I would appreciate if someone knows how to do… :slight_smile:

Thanks in advance.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.