Google Apps Script and Big Query - tabledate.insertAll - google-apps-script

Have been struggling with this..... Google Apps Script and the Big Query API are working well however when I try to use BigQuery.Tabledata.insertAll I keep getting an error saying 'no such field'.
When I try to run the same thing through the Google API explorer it works fine. The documentation says the command is :
BigQuery.TableData.insertAll(TableDataInsertAllRequest resource, String projectId, String datasetId, String tableId)
I have constructed the TableDataInsertAllRequest resource as per the documentation https://developers.google.com/bigquery/docs/reference/v2/tabledata/insertAll and it looks like this :
{
"kind": "bigquery#tableDataInsertAllRequest",
"rows":
[
{
"json":
{
"domain": "test",
"kind": "another test"
}
}
]
}
This matches my table schema.
When I run the command the error returned is :
{
"insertErrors": [
{
"index": 0,
"errors": [
{
"message": "no such field",
"reason": "invalid"
}
]
}
],
"kind": "bigquery#tableDataInsertAllResponse"
}
As I say the same TableDataInsertAllRequest resource works fine in the API explorer (clicking Try It on the documentation page above) it just does not work through Apps Script.
Any help gratefully received.

I've run into this too, and had somewhat better luck with this variation.
var rowObjects = [];
// Generally you'd do this next bit in a loop
var rowData = {};
rowData.domain = 'test';
rowData.kind = 'another test';
rowObjects.push(rowData);
// And at this point you'd have an array rowObjects with a bunch of objects
var response = BigQuery.Tabledata.insertAll({'rows': rowObjects}, projectId, datasetId, tableId);
Some things to note:
I don't indicate a kind -- it is implied by the call to insertAll()
I use dot notation (is that the right term?) rather than strings to stuff attributes into my "row objects"
I'm not sure which of these is the Secret Sauce. Anyways, in the end, the structure of the call looks about like this:
BigQuery.Tabledata.insertAll({'rows' : [
{
'domain' : 'test',
'kind' : 'another test'
}
]
},
projectId,
datasetId,
tableId);

Related

GoogleJsonResponseException: Field name is required

I'm working with the Google Analytics API for the first time and I'm trying to create a new property. I wrote a JS function in Google App Script:
function insertProperty() {
var resource =
{
// "accountId": "177832616",
"resource":{
"name": "Test Property 7",
// "dataRetentionResetOnNewActivity": false,
"websiteUrl": "https://www.test.com"
}
}
var accountID = '177832616';
var request = Analytics.Management.Webproperties.insert(resource, accountID);
// request.execute(function (response) { console.log(property.id) });
}
This is the error the API throws:
GoogleJsonResponseException: API call to analytics.management.webproperties.insert failed with error: Field name is required. (line 56, file "Code")
The insert() method seems to take two parameters: insert(Webproperty resource, string accountId);
Since it's not recognizing the name key/value I added to resource, my guess is I haven't declared the variable as a Webproperty type and I'm not sure how to do this. I assumed Webproperty was a { } variable type, but at this point I'm not sure what to try next. Doing research online, I'm not able to find anything regarding the API's Webproperty so any context/info is helpful.
From your question, I could understand that Google Analytics API is used with Advanced Google services of Google Apps Script. In this case, resource of Analytics.Management.Webproperties.insert(resource, accountId) can directly use the request body of the method of "Web Properties: insert". I think that the reason of your error is due to this. So please modify as follows and test it again.
From:
var resource =
{
// "accountId": "177832616",
"resource":{
"name": "Test Property 7",
// "dataRetentionResetOnNewActivity": false,
"websiteUrl": "https://www.test.com"
}
}
To:
var resource = {
"name": "Test Property 7",
"websiteUrl": "https://www.test.com"
}
Note:
When accountId is not correct, an error occurs. Please be careful this.
From iansedano's comment, in this case, request of var request = Analytics.Management.Webproperties.insert(resource, accountID); directly returns the values. So you can see the value like console.log(request) and console.log(request.toString()).
Reference:
Web Properties: insert

Firebase Request simplification and error fixing

I have a bunch of forms that input data into my firebase database using a express API and cloud functions.
I have one main issue - I'm getting a error on trying to test my API when inputting the form data.
The secondary issue is more, is there a cleaner way to take the inputted form data to the firebase than how I am currently doing it.
This is the code to create a new workflow (which is the data outputed from the forms)
(this is the required code from the route file)
const {getAllWorkflows,
postOneWorkflow} = require('./handlers/workflow');
// Workflow Routes
app.get('/Workflows', getAllWorkflows);
app.post('/Workflow', postOneWorkflow);
And this is the request code from a handler file
exports.postOneWorkflow = (req, res) => {
const newWorkflow = {
completed: req.body.completed,
currentStep: req.body.currentStep,
createdAt: new Date().toISOString(),
Reason: req.body.Reason,
breach: req.body.breach,
cauInd: req.body.cauInd,
cauOth: req.body.cauOth,
cauWea: req.body.cauWea,
claimEoT: req.body.claimEoT,
dateAware: req.body.dateAware,
dateEoTClaim: req.body.dateEoTClaim,
daysClaimed: req.body.daysClaimed,
dec: req.body.dec,
delayRespon: req.body.delayRespon,
descB: req.body.descB,
descCau: req.body.descCau,
descExt: req.body.descExt,
event: req.body.event,
eviCause: req.body.eviCause,
eviExtent: req.body.eviExtent,
ifGranDay: req.body.ifGranDay,
notice: req.body.notice,
proMitPro: req.body.proMitPro,
proResPro: req.body.proResPro,
recWri: req.body.recWri,
stepsMit: req.body.stepsMit,
stepsPre: req.body.stepsPre
};
db.collection("Workflow")
.add(newWorkflow)
.then(doc => {
const resWorkflow = newWorkflow;
resWorkflow.WorkflowId = doc.id;
res.json(resWorkflow);
})
.catch(err => {
res.status(500).json({ error: "something went wrong" });
console.error(err);
});
};
I'm currently receiving an error of
SyntaxError: Unexpected token c in JSON at position 10
when inputting json using postman to the workflow post route,
{
completed: "False",
currentStep: 1,
claimEoT: "True",
event: "True",
notice: "True",
recWri: "True",
dateEotClaim: "",
dateAware: "",
eviCause: "",
descCau : "",
eviExtent : "True",
descExt : "",
daysClaimed : 5,
delayRespon : "True",
proResPro : 1,
stepsPre : "True",
proPrePro : 1,
stepsMit: "True",
proMitPro : 10 ,
breach : "True",
descB : "describe",
cauInd : "True",
cauWea : "True",
cauOth : "True",
dec : "True",
ifGranDay : 5,
Reason : "I AM THE SENATE"
}
Not 100% sure why as it seems like my formatting is fine?
With creating the query - I wonder if there is a more efficient way of doing this other than writing an ungodly amount of code for the queries.
The point is I need to be able to query the different collections and edit them, but I feel like a query that just took in what it was told, and sent it through to this database, without having to specify the specific "completed", or "Reason",would be ideal.
Your postman JSON is invalid. The keys are also supposed to be enclosed in quotes.
{
"completed": "False",
"currentStep": 1,
...
}
You can just create the newWorkflow object from req.body!
const newWorkflow = req.body;
newWorkflow.createdAt = new Date().toISOString();

Error when deserializing to ProblemDetails with System.Text.Json.JsonSerializer. .Net Core 3.0

Consider the following json:
{
"title": "SOME TITEL",
"status": 500,
"detail": "Some detail",
"errors": [
{
"Parameter": "SOME VALUE",
"Code": "SOME CODE",
"Message": "SOME MESSAGE",
"Details": "SOME EXTRA DETAILS"
}
]
}
It is generated by an API response that construct a problem details like this:
var problemDetails = new ProblemDetails
{
Status = StatusCodes.Status500InternalServerError;
Detail = "DETAIL";
Title = "TITLE";
};
var customClass = new CustomCalss
{
Code = "INTERNAL_SERVER_ERROR",
Message = "Some message",
Details = "Extra details"
};
problemDetails.Extensions.Add(new KeyValuePair<string, object>("errors", new [] { customClass }));
When trying to deserialize the json to a problem details using System.Text.JsonSerialiser i found the following issues:
Status, Code and Title are not deserialised to the problem details properties, they are null
Extension data is not deserialized.
I'm testing this behavior like this:
var json = #"{
""title"": ""SOME TITLE"",
""status"": 500,
""detail"": ""Some detail"",
""errors"": [
{
""Parameter"": null,
""Code"": ""SOME CODE"",
""Message"": ""SOME MESSAGE"",
""Details"": ""SOME EXTRA DETAILS""
}
]
}";
var result = JsonSerializer.Deserialize<ProblemDetails>(json);
Assert.NotNull(result.Detail);
Assert.NotNull(result.Title);
var customClass = Assert.IsType<CustomCalss[]>(result.Extensions["errors"]);
var error = customClass.First();
Assert.Equal("INTERNAL_SERVER_ERROR", error.Code);
Any insights?
C# is a case sensitive language, something wrong with your JSON string, the key must exactly same with the property of the target class. I changed the "title" to "Title" and then got the correct value, attached here for your reference:
Updated on 11/20:
Did not noticed that it is a MVC internal class, we can simple reproduce this issue in local box now, but checked the source codes and known issues online, no existing related issue there. So I reported a new bug for this issue, attached here for your reference
https://github.com/aspnet/AspNetCore/issues/17250
Updated on 11/22:
This has been confirmed as a bug in ASP.NET Core 3.0, and fixed in 3.1 version, please upgrade to 3.1-preview2. Alternatively you could specify a custom JsonConverter based on the implementation we have in 3.1 as part of the JsonSerializerOptions that you pass when deserializing - https://github.com/aspnet/AspNetCore/blob/release/3.1/src/Mvc/Mvc.Core/src/Infrastructure/ValidationProblemDetailsJsonConverter.cs

Reading json file in node.js

This must be something really silly. After spending the last few hours, I am here for help.
I have a users.json file
{
"Test_Session": {
"test_SessionID": [
{
"$": {
"id": "1"
},
"test_type": [
"1"
],
"Test_IDtest": [
"1"
],
"DataURL": [
"data1"
]
}
]
}
}
I try to read DataURL by
var jsonData = require('./users.json');
var test = JSON.stringify(jsonData)
console.log(test.Test_Session.test_SessionID.DataURL);
In console, I get "Can't read property test_SessionID of undefined".
What's going on?
Your main issue is that test_SessionID is an array, so when you try to access DataUrl, it will be undefined. You need to select the index of the test_SessionID object you want to read from. Try this:
console.log(test.Test_Session.test_SessionID[0].DataURL);
Also, you don't need to JSON.stringify anything, Node automatically reads the file in as JSON, so just doing
var jsonData = require('./users.json');
console.log(jsonData.Test_Session.test_SessionID[0].DataURL);
should work fine.
Node is already interpreting the JSON, try the following:
var test = require('./users.json');
console.log(test.Test_Session.test_SessionID[0].DataURL);

Writing to Firebase from GAS returns error

I am trying to write to Firebase from Google Apps Script.
I try this:
var act="https://SampleChat.firebaseIO-demo.com/users/fred/name.json";
UrlFetchApp.fetch(act,{"method":"post","payload":"test"});
and I get this error:
Request failed for https://SampleChat.firebaseIO-demo.com/users/fred/name.json
returned code 400. Truncated server response:
{ "error" : "Invalid data; couldn't parse JSON object, array, or value.
Perhaps you're using invalid characters in your key names." }...
Question
How do I write to Firebase from GAS? (What am I doing wrong?)
Answer
You must stringify the payload object.
Here is a question and answer example.
I tested it and it does work.
Example
function putToFire() {
var payload = '{ "first": "Foo", "last": "Bar" }';
var options = {
"method": "put",
"payload": payload
};
UrlFetchApp.fetch(
"https://SampleChat.firebaseIO-demo.com/users/fred/name.json",
options
);
}
The Key Trick
Notice the single quotes ' around the payload object?
In the following line:
var payload = '{ "first": "Foo", "last": "Bar" }';
That counterintuitive syntax seems to be the trick to making this work. ;-)
Alternative Syntax for Variable Payloads
If your payload is a variable, you can use JSON.stringify():
var payload=JSON.stringify({"first":"Foo","last":"Bar"});