Unable to use Datastore emulator with Nodejs application - javascript

I am trying to use datastore emulator with my nodejs application
Initially I have followed the instructions given in here
Then in my node application :-
var config = {
projectId : "scio1-ts-datastore"
}
const datastore = require("#google-cloud/datastore")
const db = new datastore.Datastore(config)
const setdata = async () => {
await db.save(({
key : db.key('orders') ,
data : {
orderId : 1 ,
orderType : "Hazardous"
}
}))
}
const getdata = async () => {
const query = db.createQuery('orders')
const [orders] = await db.runQuery(query)
console.log(orders)
}
setdata()
getdata()
After this I had to run gcloud auth application-default login which I think is not needed to run as I am using datastore Emulator .
But even after this I am unable to run the app
Following error pops up :-

Not sure if this is the same issue, but for me a problem was that nodejs client did not "listen" to the environmental variables I set up (as part of the instructions you linked) and I had to initialize the datastore with endpoint explicitly given:
this.datastore = new Datastore({
apiEndpoint: "0.0.0.0:8081"
});
or whichever port the emulator says it's listening on.
Also make sure that the ~/.config/gcloud directory contains the application_default_credentials.json - unsure if emulator really needs it, but it worked for me after these steps.
Edit: if you are running the app through webstorm or such, it's good to note that environmental variables are loaded when you start it. So if it's already running when you set the variables, restart it!

Related

Why does my code thing deployed() is not a function?

code:
loadContract: async ()=>{
//Create JS version of smart contract
const todoList = await $.getJSON('TodoList.json')
App.contracts.TodoList = TruffleContract(todoList)
App.contracts.TodoList = web3.setProvider(new Web3.providers.HttpProvider("http://127.0.0.1:7545"))
//getting values from blockchain
App.todoList = await App.contracts.TodoList.deployed()
console.log(todoList)
error:
TypeError: App.contracts.TodoList.deployed is not a function
I am able to call TodoList.deployed() in the truffle dev environment but not in the JavaScript file. I am trying to to set all the data from the deployed smart contract to App.todoList so I can work with the values in the JavaScript file and render them to the HTML. I am completely stuck. When I console.log(todolist) I receive the JSON of the smart contract.
Here is my migrations file.
//need migration to update state of blockchain
const TodoList = artifacts.require("./TodoList.sol");
module.exports = function (deployer) {
deployer.deploy(TodoList);
};
//run migration and deploy contract to blockchain

Problem using google spreadsheet as source for a Next.JS website: changes won't update pages

I made this restaurant's website and uses Google Spreadsheet to feed content into the menu pages. The choice of such method was based on simplicity and client expertise.
I'm using google-spreadsheet package to fetch all the information I need from this document on Google Drive...
//** ../pages/api/cardapios/index.js
import { GoogleSpreadsheet } from "google-spreadsheet";
export default async function getCardapioFromSlug(indexNumber) {
try {
const doc = new GoogleSpreadsheet(<%GOOGLE_SPREADSHEET_ID%>)
await doc.useServiceAccountAuth({
client_email: process.env.GOOGLE_SHEETS_SERVICE_ACCOUNT_EMAIL,
private_key: process.env.GOOGLE_SHEETS_PRIVATE_KEY,
});
await doc.loadInfo()
const cardapio = doc.sheetsByIndex[indexNumber]
const rows = await cardapio.getRows()
if (rows.length) {
return rows.map(({
Código,
Produto,
Unidade,
Descrição,
Valor,
Procedência,
Categoria
}) => {
return {
Código,
Produto,
Unidade,
Descrição,
Valor,
Procedência,
Categoria
}
})
}
} catch (err) {
console.log(err)
}
return [];
}
...then feeding it into the page using getStaticProps() function. It worked like a charm once I've got all things setup properly.
// ../pages/unidades/[slug].js
export async function getStaticProps({ params }) {
const sanityData = await getCardapio(params.slug)
const indexNumber = sanityData[0].id
// console.log("index number", indexNumber)
const produtos = await getCardapioFromSlug(indexNumber)
const produtosStringfied = JSON.stringify(produtos)
const produtosArray = JSON.parse(produtosStringfied)
return {
props: {
cardapio: {
info: sanityData[0] || null,
items: produtosArray || null
}
},
revalidate: 1
}
}
The problem is after we changed values for some cells in the source document, the content wasn't automatically updated in the site.
I've tried redeploying (with both build cache on and off) it so the build process would grab the content from the document one more time and update the site, but it didn't worked. One idea was to make a webhook that would be avaiable for the client to run a simple command on his machine and rebuild the page with the new info, but this approach seems to be useless.
I red some articles (this one for instance) on custom webhooks for Google Spreadsheets but I can't really understand how it would trigger something on my page. Don't really think it would actually work.
Now I'm kind of stuck on where should I go. Perhaps I should rewrite my getStaticProps()?
The issue has nothing to due with the code itself, but the misuse of the API. The id from the spreadsheet was wrong, still using a prototype which was used as base to the final one the client has. Changed the env var and everything went fine.
Had to force deploy ignoring build cache via vercel cli. Thanks to anyone that spent time commenting and wondering about this issue.

FirebaseError: [code=invalid-argument]: Function setDoc() called with invalid data

I am using Firebase SDK's within Node-red (as specified in NPM docs they can be used for IoT devices with NODE.js).
I can use all of the CRUD methods with Firebase RealtimeDatabase.
With Firebase Firestore I can only use READ and DELETE functionality.
SET and UPDATE results in weird errors that I couldn't find answers
anywhere on the internet.
I am importing Firebase SDK's through require() inside settiings.js and functionGlobalContext so I can access them in Node-red functions:
functionGlobalContext: {
firebase: require('firebase/app'),
firebaseDatabase: require('firebase/database'),
firebaseFirestore: require('firebase/firestore'),
// os:require('os'),
// jfive:require("johnny-five"),
// j5board:require("johnny-five").Board({repl:false})
},
First I initialize my whole Firebase project with this code (and everything initializes fine without errors):
//Load data from Global contexta
const firebase = global.get('firebase');
const firebaseDatabase = global.get('firebaseDatabase');
const firebaseFirestore = global.get('firebaseFirestore');
const firebaseConfig = {
//my Firebase credentials
};
//Set up Firebase
const app = firebase.initializeApp(firebaseConfig);
const database = firebaseDatabase.getDatabase();
const firestore = firebaseFirestore.getFirestore();
//Save the database reference to Global context
global.set('app', app);
global.set('database', database);
global.set('firestore', firestore);
And here I am trying basic SET operation with Firestore:
const ft = global.get('firebaseFirestore');
const firestore = global.get('firestore');
const frankDocRef = ft.doc(firestore, "users", "frank");
await ft.setDoc(frankDocRef, {
name: "Frank",
age: 12
});
Unfortunately even though this code is ctrl+c ctrl+v from Firestore docs I get this error:
"FirebaseError: [code=invalid-argument]: Function setDoc() called with invalid data. Data must be an object, but it was: a custom Object object (found in document users/frank)"
When I use the same code inside a web app everything works fine.
There has to be something going on under the hood with Node-red
I tried creating the object using various methods and all of them resulted in the same error.
Does anybody have any idea what could be going wrong here?

Unable to get all the jobs inside a cluster using #kubernetes/client-node

I am using #kubernetes/client-node to access Kubernetes server API. I can get all the Pods from default using:
const k8s = require('#kubernetes/client-node');
const kc = new k8s.KubeConfig();
kc.loadFromDefault();
const k8sApi = kc.makeApiClient(k8s.CoreV1Api);
k8sApi.listNamespace().then((res) => { // or using listAllNamespacedPods
console.log(res.body);
});
and the body of the response from the above code looks like this:
but when I am using kc.loadFromFile('pathToKubeConfigFile'), it is unable to read it (the config.yaml which is saved inside .kube folder).
I have checked all the paths to certificates and keys files inside this file and they are correct.
import { KubeConfig, CoreV1Api } from '#kubernetes/client-node';
const kc = new KubeConfig();
kc.loadFromFile('./config/k8sConfig.yaml');
const k8sApi = kc.makeApiClient(CoreV1Api);
k8sApi.listPodForAllNamespaces().then((res) => {
console.log(res.body);
});
and I need to return all the active Kubernetes Jobs (or the pods for that). Can anyone please suggest me how to achieve it?
As the problem has already been resolved in the comments section, I decided to provide a Community Wiki answer just for better visibility to other community members. I would also like to describe how to return all active Kubernetes Jobs using the Javascript Kubernetes Client
Using the loadFromFile() method.
When using the loadFromFile() method, it's important to make sure that the kubeconfig file is correct. In case the kubeconfig file is invalid, we may get various error messages such as:
Error: ENOENT: no such file or directory, open '.kube/confi'
or
Error: unable to verify the first certificate
The exact error message depends on what is incorrect in the kubeconfig file.
List all/active Kubernetes Jobs.
To list all Kubernetes Jobs, we can use the listJobForAllNamespaces() method.
I've created the listAllJobs.js script to demonstrate how it works:
$ cat listAllJobs.js
const k8s = require('#kubernetes/client-node')
const kc = new k8s.KubeConfig()
kc.loadFromFile('.kube/config')
const k8sApi = kc.makeApiClient(k8s.BatchV1Api);
k8sApi.listJobForAllNamespaces().then((res) => {
res.body.items.forEach(job => console.log(job.metadata.name));
});
$ kubectl get jobs
NAME COMPLETIONS DURATION AGE
job-1 0/1 3s 3s
job-2 1/1 10s 48m
job-3 1/1 10s 48m
$ node listAllJobs.js
job-1
job-2
job-3
To list only active Jobs, we need to slightly modify the res.body.items.forEach(job => console.log(job.metadata.name)); line to check if the Job is active:
$ cat listActiveJobs.js
const k8s = require('#kubernetes/client-node')
const kc = new k8s.KubeConfig()
kc.loadFromFile('.kube/config')
const k8sApi = kc.makeApiClient(k8s.BatchV1Api);
k8sApi.listJobForAllNamespaces().then((res) => {
res.body.items.forEach(job => job.status.active >= 1 && console.log(job.metadata.name));
});
$ kubectl get jobs
NAME COMPLETIONS
job-1 0/1
job-2 1/1
job-3 1/1
$ node listActiveJobs.js
job-1
You have to pass the Kube config file location instead of any YAML file
const { KubeConfig } = require('kubernetes-client')
const kubeconfig = new KubeConfig()
kubeconfig.loadFromFile('~/some/path')
const Request = require('kubernetes-client/backends/request')
const backend = new Request({ kubeconfig })
const client = new Client({ backend, version: '1.13' })
https://github.com/godaddy/kubernetes-client#initializing
However if you are planning to run the POD or container on K8s cluster you can also use : kc.loadFromCluster();
https://github.com/kubernetes-client/javascript/blob/master/examples/in-cluster.js
If you want to pass any YAML and apply those changes to cluster you can use the
https://github.com/kubernetes-client/javascript/blob/master/examples/yaml-example.js

Why is my aws step function's execution not started with the ARN I entered?

I'm creating a new state machine with AWS Step functions in the project I'm working on. But when I try to start the execution of the step function with the aws-sdk, I get a "StateMachineDoesNotExist" error. It seems like the stateMachineArn I pass as input is not the same used by the startExecution function.
Here is how I'm trying to start the execution:
const AWS = require('aws-sdk')
const stepfunctions = new AWS.StepFunctions()
const params = {
stateMachineArn: process.env.ORDER_ACCEPTED_MACHINE_ARN,
name: `${orderId}-${moment().unix()}`,
input: JSON.stringify({
orderAcceptedTimestamp: moment(createdAt).add(1, 'minutes').toISOString(),
orderId,
}),
}
const success = await stepfunctions.startExecution(params).promise()
return success.executionArn
My stateMachineArn is defined this way :
process.env.ORDER_ACCEPTED_MACHINE_ARN = 'arn:aws:states:eu-central-1:935080471983:stateMachine:orderAcceptedMachine-dev'
And here is the error message I get when running the code:
State Machine Does Not Exist: 'arn:aws:states:us-east-1:935080471983:stateMachine:orderAcceptedMachine-dev'
What I don't understand here is that the Arn from the input and the Arn from the error are not the same. To me it seems like the startExecution modified the input stateMachineArn and changed its region somehow (even though the Arn is passed as a string?!).
I already have a similar step functions in the project that I start the same way:
const params = {
stateMachineArn: process.env.ORDER_TIMEOUT_MACHINE_ARN,
name: `${orderId}-${moment().unix()}`,
input: JSON.stringify({
orderTimeoutTimestamp: timeout.toISOString(),
orderId,
}),
}
const success = await stepfunctions.startExecution(params).promise()
return success.executionArn
The Arn definition is in the same file as the other one, and is defined like this:
process.env.ORDER_TIMEOUT_MACHINE_ARN = 'arn:aws:states:eu-central-1:935080471983:stateMachine:orderTimeoutMachine-dev'
This step functions is started with no problem and correctly return the Arn of the execution.
By debugging I found out that AWS.config.region returns us-east-1 in both files where I call startExecution. Since my existing state machine is already working with this configuration, I'm thinking it's not related to the error, but I tried to 'force' the AWS Region to eu-central-1 anyway just before the call like this:
AWS.config.update({ region: 'eu-central-1' })
const success = await stepfunctions.startExecution(params).promise()
But this doesn't solve the issue. I am fairly new to AWS so there is probably something that I'm missing out here (Let me know if I forgot to put any important code/info), but I'm really confused by the facts that the Arn in the error message doesn't match the one in the input, and that an almost identical state machine is working fine while my newly created one doesn't want to start.
So how can I fix this issue ?
After further investigation I found out that the step functions's region and endpoint can be different from AWS. Adding the following code solved the issue:
const stepfunctions = new AWS.StepFunctions({
endpoint: 'https://states.eu-central-1.amazonaws.com',
region: 'eu-central-1',
})

Categories