I'm talking to Nest Cloud API using Nodejs using firebase node module. I'm using accessToken that I got from https://api.home.nest.com/oauth2/access_token, and this seems to work. My Nest user account got prompted to "accept" this request, which I did and my app is listed in the Nest Account "Works with Nest" page so all looks good. I use this accessToken in call to authWithCustomToken and that works and my Nodejs application requested read/write permission (See https://developers.nest.com/products/978ea6e2-c301-4dff-8b38-f63d80757162). And reading the Nest thermostat properties from https://developer-api.nest.com/devices/thermostats/[deviceid] works, but when I try and write to hvac_mode like this:
this.firebaseRef = new Firebase("https://developer-api.nest.com");
this.myNestThermostat = this.firebaseRef.child("devices/thermostats/"+deviceId);
this.myNestThermostat.set("{'hvac_mode': 'off'}", function (error) { ... }
and this always returns:
FIREBASE WARNING: set at /devices/thermostats/fwxNBtjaok6KZJbSXhf2azuBmGSvkcjK failed: No write permission(s) for field(s): /devices/thermostats/fwxNBtjaok6KZJbSXhf2azuBmGSvkcjK
(where the deviceId is what I see when I enumerate my devices, I only have one, so I'm pretty sure it is correct).
Any ideas?
Well, isn't that always the case, I found an answer already. Turns out if I create a firebase reference to the property itself like this:
var propertyRef = this.myNestThermostat.child(name);
Then the following succeeds:
propertyRef.set(value, function (error) { ...
The firebase documentation was misleading on this because it led me to believe I could write this:
this.myNestThermostat.set("{'hvac_mode': 'off'}", function (error) { ... }
which technically should have worked, but I guess that would mean I'd need write access on the whole of this.myNestThermostat, which I don't. Tricky.
Anyway I'm happy because it works now, yay! Firebase + nodejs rocks!
Related
Installed the google cloud pub sub following instructions from the following link,
https://cloud.google.com/pubsub/docs/reference/libraries
Imported that as the following,
const { PubSub } = require("#google-cloud/pubsub");
const projectId = "projectXYZ";
const pubSubClient = new PubSub({ projectId });
export async function publishMessage(topicName, data) {
return await pubSubClient.topic(topicName).publish(JSON.stringify(data));
}
this leads to the following error,
Now, what I have observed is that the code below the import has no significance in this issue, since this error still appears even if I only import on the first line.
Am I missing something or required to install something more that just the package?
Any help is deeply appreciated.
Thank you in advance.
Library maintainer here! I'm guessing from the stack trace that you're using webpack on your app? Right now we don't have webpack and rollup support - there are a few weird things like what you see above. Your code looks okay. We'd like to get webpack and similar tools working at some point for server-side usage, but it hasn't gone very high on the priority list just yet. I think the previous assumption was that people were trying to use it in a web browser, which we don't recommend for a number of reasons (most prominently, security concerns with GCP credentials). But I've been seeing a lot of issues with users trying to use webpack on the server side to make their Cloud Functions more compact, which seems pretty legit. I'll bring it up in our next team sync.
If you're not using webpack, then that sounds like something that might be filed over at the issue tracker.
I'm trying to disable the Cloudwatch Event Rule that is triggering a Lambda, within the Lambda itself, so that it doesn't keep running when it's not necessary to do so.
I have a separate Lambda that is calling enableRule to enable the rule, which seems to work fine. The rule is not associated with the function that is doing enableRule. EDIT: Turns out the EnableRule doesn't work in Lambda either.
However, this Lambda that's supposed to disable it isn't working.
Both functions already have Cloudwatch and CloudwatchEvent Full Access rights in their roles.
var cloudwatchEvents = new AWS.CloudWatchEvents();
var params = {
Name: cloudwatchEventRuleName
}
console.log("this message will show up");
cloudwatchEvents.disableRule(params, function (err, data) {
console.log("but this message never appears when it runs via Lambda for some reason!")
if (err)
console.log(err,err.stack);
else
console.log(data);
});
console.log("and this message will also show up");
That line where it was supposed to call the middle console.log doesn't work at all if I run it through Lambda. It's working perfectly in my local, however.
I even printed the cloudwatchEventRuleName to check if I have any typos, but the function name seems right. It's like the function is just outright skipping the disableRule function altogether for whatever reason.
So apparently, years later, setting up VPCs still haunt me.
Yep, it's a VPC configuration thing.
I could swear that the Subnet that the Lambda function was using had a route table that pointed to a properly set up Network Interface with a NAT Gateway Instance.
Out of curiosity, I tried making the route table entry of 0.0.0.0/0 point to the instance (i-#####) rather than the network interface (eni-######).
After I pressed Save in the Route Table, it automatically transformed into eni-######, similar to what I already had it set up...
Except this time the function actually started working now.
I have no idea what kind of magic AWS did so that associating an instance =/= associating to a network interface even though the former transformed into the same ID anyway, but whatever.
So for anyone encountering this same problem: always remember to double-check if your function actually has access to the internet to use the AWS APIs.
EDIT: Also another thing: I had to make sure that enableRule and disableRule were both awaited, as for some reason the AWS requests can in fact not be sent properly if the handler already returned something before the request was completed. So we turned into a promise just so we can await it:
try { await cloudwatchEvents.disableRule(params).promise().then((result) => console.log(result)) }
catch (error) { console.log("Error when disabling rule!", error); }
I have followed the Tutorial and build the basic CF based nodejs applciation to display all BusinessPartners from my S/4HANA on-premise destination.
function getAllBusinessPartners(): Promise<BusinessPartner[]> {
return BusinessPartner.requestBuilder()
.getAll()
.execute({
destinationName: 'MockServer'
});
}
Destination is configured with the Virtual host from cloud connector.
But after deploying to the Cloud Foundry, i get following error for the GET request
{"message":"Service of type destination is not supported! Consider providing your own transformation function when calling destinationForServiceBinding, like this:\n destinationServiceForBinding(yourServiceName, { serviceBindingToDestination: yourTransformationFunction });","level":"warn","custom_fields":{"package":"core","messageContext":"destination-accessor"},"logger":"sap-cloud-sdk-logger","timestamp":"2020-03-09T18:15:41.856Z","msg":"Service of type destination is not supported! Consider providing your own transformation function when calling destinationForServiceBinding, like this:\n destinationServiceForBinding(yourServiceName, { serviceBindingToDestination: yourTransformationFunction });","written_ts":1583777741856,"written_at":"2020-03-09T18:15:41.856Z"}
The application is already bound to the Destination service as well.
Can someone help me here, what went wrong ? or the approach to use destination is different in the new version of Cloud-SDK ?
After lot of attempts, i have made this to work.
My Observations:
Connectivity service is also required to be bound, when using on-premise S4 backend.
There was no errors in the log, i have made certain modification in the code to use async/await
async function getAllBusinessPartners(): Promise<BusinessPartner[]> {
return await BusinessPartner.requestBuilder()
.getAll()
.execute({
destinationName: 'MockServer'
});
}
After this modification, when I hit the GET request, it gave me the following error:
"Failed to get business partners - get request to http://s4h-scc-basic:500/sap/opu/odata/sap/API_BUSINESS_PARTNER/sap/opu/odata/sap/API_BUSINESS_PARTNER failed!"
Could notice that the suffix after the http://domain:port is twice. One I gave in the destination, and the other VDM adds automatically.
Ideally, this error is supposed to be thrown even before adding async/await.
After removing the suffix from the destination, it started to work.
If your request really does error, what you posted here from your logs is most likely not the reason for the failure. We are aware that this message is confusing and will improve it (https://github.com/SAP/cloud-sdk/pull/32).
Can you check whether there are more errors in your logs? Based on the code you posted and the setup you described, this should work. Do you have a binding to the XSUAA service.
I've got some problems while calling the function <async> getUserContext(name, checkPersistence), so far I know it fails only when I try to get the context of an existing user, but it does work with non existing users.
The code I use to create the client object and call the function is as follows:
const config = '-connection-profile-path';
const client = hfc.loadFromConfig(hfc.getConfigSetting(`network${config}`));
client.loadFromConfig(hfc.getConfigSetting(`${this.orgId}${config}`));
await client.initCredentialStores();
const admin = await client.getUserContext('admin', true);
And the error is:
[2019-10-04 11:41:38.701] [ERROR] utils/registerUser - TypeError:
Cannot read property 'curve' of undefined
which, as far as I know, makes no sense. The only solution I`ve found is to check if the certificates are up to date, that is deleting it and let runApp.sh & setupAPIs.sh (I'm using the balance-transfer example from hyperledger/fabric-samples) create the folder again with all those certificates.
I found that the only problem was that the users inside the docker container I was using were desynced with the ones in the State Store. So if you are using docker make sure to keep the users synchronized.
In order to setup Google Identity Toolkit for my Website I started with the Quick-start App for Node.js.
It worked fine on localhost.
But when I moved it to an actual app-engine instance it did not work anymore.
I got this error returned by gitkitClient.verifyGitkitToken():
Invalid token: Unable to verify the ID Token: Wrong recipient, payload
audience != requiredAudience
I found a very helpful post on stackoverflow about more or less the same issue, for Java instead of node.js: It looks like there is a mismatch between projectId and clientId.
I changed my gitkit-server-config.json file to swap the projectId and clientId values and it worked!
This sound very much like a major bug on google side, doesn't it?
Why does it work on localhost?
Will this be changed/fixed in the future?
Maybe the problem is in the tutorial?
I have a working solution for now, but I do not feel safe to keep it like that...
I hope a googler will read this!
[EDIT]
Following wyhao31's comment I had a closer look at the gitkitclient.js source code and both projectId and clientId are added to the same audiences array.
After more test I found out that you must only put the project ID ('my-project-name') in the gitkit-server-config.json file.
The nasty thing is that if you add it with a 'clientId' property name it is also working...
Based on your description, and if you read gitkit-server-config.json file like this
var gitkitClient = new GitkitClient(JSON.parse(fs.readFileSync('./gitkit-server-config.json')));
I think the problem might caused by using old nodejs client lib. Could you try to update your client lib to latest version(0.0.6)? Or you can use the code directly.