How to send hierarchical data from firebase to google sheet - firebase-realtime-database

below is the hierarchy of my data present in firebase database. I want to send this data to google sheet but I am unable to do so.
Error stated by google sheet is "TypeError: Cannot read property "rytf1JLXetTIINjHNku0yAvs7su2" from undefined.
Details"
Below is the code that I am trying to retrieve data. Kindly let me know the mistake. Thank you!
function writeSheets() {
var ss = SpreadsheetApp.openById("google-sheet-id");
var firebaseUrl = "database-url";
var base = FirebaseApp.getDatabaseByUrl(firebaseUrl);
var data = base.getData('users/admin');
Logger.log(data);
var num = 2;
range = ss.getRange("A" + num + ":E" + num + "");
for (var i in data) {
var values = [
[
[
[data][data][i] // Error occurs here
].email, [
[data][data][i] // Error occurs here
].userName, [
[data][data] // Error occurs here
[i]
].Password, [
[data][data][i] // Error occurs here
].loginState, [
[data][data][i] // Error occurs here
].uid
]
];
range.setValues(values);
num += 1;
range = ss.getRange("A" + num + ":E" + num + "");
}
}
Sample Value of data
{
rytf1JLXetTIINjHNku0yAvs7su2:
{
loginDetail:
{
uid:rytf1JLXetTIINjHNku0yAvs7su2,
password:123456,
loginState:true,
userName:John,
email:a#a.com
}
}
}

From your question and comments, I thought that you want to do as follows.
You want to put the values of "email", "userName", "password", "loginState", "uid" to the Spreadsheet every row.
You want to put the value from 2nd row of the 1st sheet in the Spreadsheet.
The structure of object data is like as follows. You want to retrieve each value from the object loginDetail.
{
"rytf1JLXetTIINjHNku0yAvs7su2": {
"loginDetail": {
"uid": "rytf1JLXetTIINjHNku0yAvs7su2",
"password": 123456,
"loginState": true,
"userName": "John",
"email": "a#a.com"
}
}
};
If my understanding is correct, how about this modification?
Modification points:
Find loginDetail at the 2nd level, and the object of loginDetail is retrieved.
From the retrieved object loginDetail, each value of "email", "userName", "password", "loginState", "uid" is retrieved in order.
Values of "email", "userName", "password", "loginState", "uid" are put from the 2nd row of 1st sheet of the Spreadsheet.
Modified script:
function writeSheets() {
var ss = SpreadsheetApp.openById("google-sheet-id");
var firebaseUrl = "database-url";
var base = FirebaseApp.getDatabaseByUrl(firebaseUrl);
var data = base.getData('users/admin');
Logger.log(data);
// I modified below script.
var keys = ["email", "userName", "password", "loginState", "uid"];
var res = [];
for (var i in data) {
for (var j in data[i]) {
if (j == "loginDetail") {
res.push(keys.map(function(e) {return data[i][j][e]}));
}
}
}
var num = 2;
ss.getRange("A" + num + ":E" + (res.length + num - 1)).setValues(res);
}
Note:
If the structure of object data is changed, it is required to traverse the object. At that time, please tell me.
Reference:
getRange(a1Notation)

Related

node-red-node-firebird returns a buffer instead of a string

I'm doing KPI's in node-red, and I'm using node-red-node-firebird to connect my database and get the results from it. For that I made a query to select the columns I need, one of those is:
NAME Varchar(40), with an example value: "Pizzas"
(example: Select NAME from mytable)
When I receive the query response on node-red, I store it inside the msg.payload. The problem is the result that I get it isn't the string "Pizzas" but a buffer "NAME":{"type":"Buffer","data":[80,105,122,122,97,115]}}.
How can I get the string and not the buffer?
I already tried a lot of things, among them:
On the query I have tried cast(NAME AS varchar(40)) AS NAME; [NAME] without success. Put msg.payload.data.toString('utf-8') in function node but nothing happens, the function:
var objectData = msg.objectData; //this is the query response
//------------Columns----------------------------
var fields = [];
var i = 0;
if(objectData.length > 0) {
var data = objectData[0];
for(var key in data) {
fields[i] = key;
i++;
}
//TRY nº1
objectData.foreach(function(obj){
if (Buffer.isBuffer(obj) === true) {
obj = obj.toString('utf-8');
}
})
}
//-----------------------------------------
msg.method = "POST";
msg.url = //My api request//;
msg.headers = {};
msg.headers["Content-Type"] = "application/json";
msg.headers.Authorization = //auth//;
msg.payload = {
'groupID': 'Group123',
'companyID': 1221,
'table': 'DemoTable',
'fields': fields,
'data': objectData, //problem
'delete': true,
};
//TRY nº2
msg.payload = msg.payload.data.toString('utf-8');
return msg;
I solved my problem changing the select to:
SELECT cast(name as varchar(100) character set win1252) NOME FROM mytable
Thanks for the help :)

Google Sheet Script to pull data from YouTube API, cannot fetch channel ID

I'm trying to pull data from my YouTube channel, numbers of views, etc, into a Google sheet.
I authorized YouTube APIs, but it cannot retrieve my youtube channel ID.
Here's the error message:
Invalid number of arguments provided. Expected 0-1 only (line 31, file "Code")
line 31 is : var analyticsResponse = YouTubeAnalytics.Reports.query(
I'm using a script found online:
function testingYTpage() {
var url = "https://www.youtube.com/watch?v=ua4QGWmDfB8&list=PLOU2XLYxmsILvfJcIASBDbgfxloFz_XsU&index=7";
var rawData = UrlFetchApp.fetch(url).getContentText();
Logger.log(rawData);
}
//
//
//
function spreadsheetAnalytics() {
// Get the channel ID
var myChannels = YouTube.Channels.list('id', {mine: true});
var channel = myChannels.items[0];
var channelId = channel.id;
// Set the dates for our report
var today = new Date();
var monthAgo12 = new Date();
monthAgo12.setMonth(today.getMonth() - 11);
var todayFormatted = Utilities.formatDate(today, 'UTC', 'yyyy-MM-dd')
var oneMonthAgoFormatted = Utilities.formatDate(monthAgo12, 'UTC', 'yyyy-MM-dd');
// The YouTubeAnalytics.Reports.query() function has four required parameters and one optional
// parameter. The first parameter identifies the channel or content owner for which you are
// retrieving data. The second and third parameters specify the start and end dates for the
// report, respectively. The fourth parameter identifies the metrics that you are retrieving.
// The fifth parameter is an object that contains any additional optional parameters
// (dimensions, filters, sort, etc.) that you want to set.
var analyticsResponse = YouTubeAnalytics.Reports.query(
'channel==' + channelId,
oneMonthAgoFormatted,
todayFormatted,
// dimensions=day metrics=views,estimatedMinutesWatched,averageViewDuration,averageViewPercentage,subscribersGained
'views,estimatedMinutesWatched,averageViewDuration,averageViewPercentage,likes,dislikes,shares',
{
dimensions: 'day',
sort: '-day'
});
// Create a new Spreadsheet with rows and columns corresponding to our dates
var ssName = 'YouTube channel report ' + oneMonthAgoFormatted + ' - ' + todayFormatted;
var numRows = analyticsResponse.rows.length;
var numCols = analyticsResponse.columnHeaders.length;
// Add an extra row for column headers
var ssNew = SpreadsheetApp.create(ssName, numRows + 1, numCols);
// Get the first sheet
var sheet = ssNew.getSheets()[0];
// Get the range for the title columns
// Remember, spreadsheets are 1-indexed, whereas arrays are 0-indexed
var headersRange = sheet.getRange(1, 1, 1, numCols);
var headers = [];
// These column headers will correspond with the metrics requested
// in the initial call: views, likes, dislikes, shares
for(var i in analyticsResponse.columnHeaders) {
var columnHeader = analyticsResponse.columnHeaders[i];
var columnName = columnHeader.name;
headers[i] = columnName;
}
// This takes a 2 dimensional array
headersRange.setValues([headers]);
// Bold and freeze the column names
headersRange.setFontWeight('bold');
sheet.setFrozenRows(1);
// Get the data range and set the values
var dataRange = sheet.getRange(2, 1, numRows, numCols);
dataRange.setValues(analyticsResponse.rows);
// Bold and freeze the dates
var dateHeaders = sheet.getRange(1, 1, numRows, 1);
dateHeaders.setFontWeight('bold');
sheet.setFrozenColumns(1);
// Include the headers in our range. The headers are used
// to label the axes
var range = sheet.getRange(1, 1, numRows, numCols);
var chart = sheet.newChart()
.asColumnChart()
.setStacked()
.addRange(range)
.setPosition(4, 2, 10, 10)
.build();
sheet.insertChart(chart);
}
//
// A Helper function to extract the ID of our video
// It works both on version of links:
// 1. https://www.youtube.com/watch?v=BuHEhmp47VE
// 2. http://youtu.be/BuHEhmp47VE
//
function extractVideoID() {
var curSheet = SpreadsheetApp.getActiveSheet();
var ytLinks = curSheet.getRange("D:D");
var totalRows = ytLinks.getNumRows();
var ytVal = ytLinks.getValues();
// let's run on the rows
for (var i = 1; i <= totalRows - 1; i++) {
var curLink = ytVal[i][0];
if (curLink == "") {
break;
}
var videoID = "";
var inx1 = curLink.indexOf('watch?v=') + 8;
if (inx1 == 7) {
// check if it's the short format: http://youtu.be/75EuHl6CSTo
if (curLink != "" && curLink.indexOf("youtu.be") > 0) {
videoID = curLink.substr(16, curLink.length);
}
}
else {
// we have the link in this format: https://www.youtube.com/watch?v=YIgSucMNFAo
var inx2 = curLink.indexOf("&", inx1);
if (inx2 > inx1) {
videoID = curLink.substr(inx1, inx2-inx1);
} else {
videoID = curLink.substr(inx1, curLink.length);
}
}
curSheet.getRange("E" + (i+1)).setValue(videoID);
}
var htmlMsg = HtmlService
.createHtmlOutput('<h3>Done - Please check the IDs on Column D:D</h3>').setTitle('YT Dashboard Example').setWidth(450).setHeight(300);
SpreadsheetApp.getActiveSpreadsheet().show(htmlMsg);
}
//
// Run on all the rows and according to the video ID fetch the feed
//
function fetchAllData() {
var start = new Date().getTime();
var curSheet = SpreadsheetApp.getActiveSheet();
var ytIds = curSheet.getRange("E:E");
var totalRows = ytIds.getNumRows();
var ytVal = ytIds.getValues();
var errMsg = "<h4>Errors:</h4> <ul>";
// let's run on the rows after the header row
for (var i = 1; i <= totalRows - 1; i++) {
// e.g. for a call: https://gdata.youtube.com/feeds/api/videos/YIgSucMNFAo?v=2&prettyprint=true
if (ytVal[i] == "") {
Logger.log("We stopped at row: " + (i+1));
break;
}
var link = "https://gdata.youtube.com/feeds/api/videos/" + ytVal[i] + "?v=2&prettyprint=true";
try {
fetchYTdata(link, i+1);
}
catch (err) {
errMsg += "<li>Line: " + i + " we could not fetch data for ID: " + ytVal[i] + "</li>";
Logger.log("*** ERR: We have issue with " + ytVal[i] + " On line: " + i);
}
}
if (errMsg.length < 24) {
// we do not have any errors at this run
errMsg += "<li> All good for now </li>";
}
var end = new Date().getTime();
var execTime = (end - start) / 1000;
var htmlApp = HtmlService
.createHtmlOutput('<h2>Done updating!</h2><p>It took us: '+ execTime + 'sec. to update: ' +
(i+1) + ' videos</p>' + errMsg).setTitle('YT Stats').setWidth(450).setHeight(450);
SpreadsheetApp.getActiveSpreadsheet().show(htmlApp);
}
//
// Read YT stats data on our videos and fill the sheet with the data
//
function fetchYTdata(url, curRow) {
//var url = 'https://gdata.youtube.com/feeds/api/videos/Eb7rzMxHyOk?v=2&prettyprint=true';
var rawData = UrlFetchApp.fetch(url).getContentText();
//Logger.log(rawData);
// published <published>2014-05-09T06:22:52.000Z</published>
var inx1 = rawData.indexOf('published>') + 10;
var inx2 = rawData.indexOf("T", inx1);
var publishedDate = rawData.substr(inx1, inx2-inx1);
// viewCount='16592'
var inx1 = rawData.indexOf('viewCount') + 11;
var inx2 = rawData.indexOf("'/>", inx1);
var totalViews = rawData.substr(inx1, inx2-inx1);
// <yt:duration seconds='100'/>
var inx1 = rawData.indexOf('duration seconds') + 18;
var inx2 = rawData.indexOf("'/>", inx1);
var durationSec = rawData.substr(inx1, inx2-inx1);
Logger.log(curRow + ") TotalViews: " + totalViews + " durationSec: " + durationSec);
// update the sheet
var ss = SpreadsheetApp.getActiveSheet();
ss.getRange("C" + curRow).setValue(publishedDate);
ss.getRange("G" + curRow).setValue(totalViews);
ss.getRange("H" + curRow).setValue(durationSec);
}
//
// Our custom menu
//
function onOpen() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [{ name : "Update Stats", functionName : "fetchAllData"},
{ name : "Extract Video IDs", functionName : "extractVideoID"}
];
spreadsheet.addMenu("YT Dashboard", entries);
};
non-scripted non-API solution (for meanwhile):
CHANNEL ID:
=ARRAYFORMULA(REGEXREPLACE(QUERY(SUBSTITUTE(ARRAY_CONSTRAIN(
IMPORTDATA(https://www.youtube.com/watch?v=rckrnYw5sOA), 3000, 1), """", ""),
"where Col1 contains '<meta itemprop=channelId content='"),
"<meta itemprop=channelId content=|>", ""))
VIEWS:
=VALUE(REGEXREPLACE(TEXT(IMPORTXML("https://www.youtube.com/watch?v=MkgR0SxmMKo",
"//*[contains(#class, 'watch-view-count')]"),0)," view(s)?",""))
MORE: https://stackoverflow.com/a/55064665/5632629
I also faced the same issue. Used the below syntax for the Reports.query method and got it worked.
YouTubeAnalytics.Reports.query({
ids: 'channel==' + channelId,
startDate: formatDateString(lastMonth),
endDate: formatDateString(today),
metrics: metrics.join(','),
dimensions: 'day',
sort: 'day'
});

how to get value from response in swift which returns [String:AnyObject] Swift4

in my Api call i getting response in [String : AnyObject] format from this i need to get few elements and store it on Array how to achieve this in Swift4 here my sample response could help how to get values from my response
My Sample Response :
["result": valid: (
{
id = 1;
"name" = "Alen"
},
{
id = 12;
"name" = "Peter"
},
{
id = 14;
"name" = "John"
},
{
id = 16;
"name" = "Ema"
},
{
id = 19;
"name" = "Shane"
},
{
id = 211;
"name" = "Mia"
}
)]
From this response i need to get all "name" values in array how to acheive this in swift 4
You can use swiftyJSON for seperate "name" from the response
let jsonData = JSON(data : data)
data - response of your api
then use forloop for adding name data in array
Hope so, this will help you.
struct Details{
let Name : String
}
And where you are getting result from server, use this code and after that your name values will be in Result Array.
var RecordsArr = [Details]()
let Result = recordJSON.value(forKey: "result") as? [NSDictionary]
for item in Result {
let id_records = Details(Name: item[“name”]! as! String)
RecordsArr.append(id_records)
}
Let me tell, if you have any problem.

Google Script to send an e-mail when a column says "YES"

I finally got the code to post here!
I figured out most of it, but just two things.
It is sending two e-mails instead of one for some reason.
I would like to print the arrays as a list like this:
object 1
object 2
etc.
instead of printing "object 1, object 2, etc" in the e-mail. Any suggestions how to do this would be helpful. Thanks!
picture of code is attached
var EMAIL_SENT = "EMAIL_SENT";
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 3;
var numRows = 2;
var dataRange = sheet.getRange(startRow, 1, numRows, 15)
var data = dataRange.getValues();
for (i = 0; i < data.length; ++i) {
var row = data[i];
if(row[6]==0) {
var emailSent = row[14];
if(emailSent != EMAIL_SENT) {
var emailAddress = row[0];
var name = row[2]
var list1 = [];
for (j = 10; j < 12; ++j) {
if(row[j] != "") {
list1.push(row[j]); //if you know how to make this print in different rows in the e-mail, that would be helpful
}
}
var list2 = [];
for (j = 12; j < 14; ++j) {
if(row[j] != "") {
list2.push(row[j]); //if you know how to make this print in different rows in the e-mail, that would be helpful
}
}
var message = " " +emailSent+ "Hello, \n\n The first part of " +name+ "'s Unit 8 Project for Geometry is due this Friday, March 23rd. This includes sections 8-1 and 8-2. By this date, students are expected to have received feedback from me on their 8-1 and 8-2 assignments and revised their work for a summative grade. Unfortunately, " +name+ " still has not submitted all of these assignments to receive feedback from me. The following assignments are currently missing: \n" +list1+ "\n\n It is also important that the independent practice be completed as well to make sure that students grasp a full understanding of what we are learning in the project. Currently " +name+ " is missing the following independent practice for these lessons: \n" +list2+ "\n\n Please check with " +name+ " to make sure these assignments are completed as soon as possible. Let me know if you have any questions about what needs to be completed for Friday. Thank you!";
var subject = "" +name+ "'s Unit 8 Project Missing Work";
MailApp.sendEmail(emailAddress, subject, message);
sheet.getRange(startRow + i, 15).setValue(EMAIL_SENT); //this doesn't work after I added the array. Any idea why?
SpreadsheetApp.flush();
}
}
}
}
var spreadsheet = SpreadsheetApp.getActive();
var menuItems = [
{name: 'Send Emails', functionName: 'sendEmails'}
];
spreadsheet.addMenu('Send Emails', menuItems);
Figured it out :)
var EMAIL_SENT = "EMAIL_SENT";
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 3;
var numRows = 13;
// Fetch the range of cells A3:I17
var dataRange = sheet.getRange(startRow, 1, numRows, 25)
var data = dataRange.getValues();
for (i = 0; i < data.length; ++i) { //collects data for all values in rows and columns specified in 5,6, and 8
var row = data[i]; //gives an index to data in each row
if(row[3]=="YES") { //ensures that it says "YES" in the e-mail column
var emailSent = row[24]; //checks value of emailSent row
if(emailSent != EMAIL_SENT) { //avoids sending duplicates if an e-mail is sent
var emailAddress = row[0]; //collects parent e-mail address
var name = row[2] //collects student name
var list1 = []; //creates an empty list for missing assignments
for (j = 15; j < 20; ++j) { //adds assignments to list if cells are not blank
if(row[j] != "") {
list1.push(row[j]);
}
}
texta = "" //creates an empty textbox for the list of assignments
if(list1.length>0) { //creates a textbox for assignments as a bulleted list if list is not empty
text1 = "";
for (k=0; k<list1.length; ++k) {
text1 += " • " +list1[k]+ "\n";
}
texta += "The second part of " +name+ "'s Unit 8 Project for Geometry is due next Tuesday, April 3rd. This includes sections 8-1, 8-2, 8-3, 8-4, and the interview/research portion. By this date, students are expected to have received feedback from me on all of their assignments and revised their work for a summative grade. Unfortunately, "
+name+ " still has not submitted all of these assignments to receive feedback from me. The following assignments are currently missing: \n" +text1;
}
var list2 = []; //creates a second empty list for missing assignments - IP
for (j = 20; j < 24; ++j) { //adds assignments to list if cells are not blank
if(row[j] != "") {
list2.push(row[j]);
}
}
textb = "" //creates an empty textbox for list of missing IP
if(list2.length>0) { //adds assignments to textbox as a bulleted list if list is not empty
text2 = "";
for (k=0; k<list2.length; ++k) {
text2 += " • " +list2[k]+ "\n";
}
textb += "\n\n It is also important that the independent practice be completed as well to make sure that students grasp a full understanding of what we are learning in the project. Currently " +name+ " is missing the following independent practice for these lessons: \n"
+text2+ "";
}
var message = "Hello, \n\n " +texta+ "" +textb+ "\n\n Please check with " //message body for e-mail
+name+ " to make sure these assignments are completed as soon as possible. Let me know if you have any questions about what needs to be completed for next week. Thank you!";
var subject = "" +name+ "'s Unit 8 Project Missing Work"; //subject line for e-mail
MailApp.sendEmail(emailAddress, subject, message); //sends e-mail with given e-mail address, subject, and message
sheet.getRange(startRow + i, 25).setValue(EMAIL_SENT); //updates spreadsheet once an e-mail is sent
SpreadsheetApp.flush(); //adds code to spreadsheet before continuing
}
}
}
}
var spreadsheet = SpreadsheetApp.getActive(); //creates a send e-mails button in spreadsheet
var menuItems = [
{name: 'Send Emails', functionName: 'sendEmails'}
];
spreadsheet.addMenu('Send Emails', menuItems);

Using Google Sheets and Google Scripts - How do I insert an entry from a cell into a variable?

This is my first time playing with a JSON API and my java is super rusty.
I'm trying to do the following:
Pull a string from a Google Sheets cell into function getSymbol (name). In this case, the string should be "Ethereum"
Insert the name variable into a url string, which is where the JSON I want to pull lives. In this case, the API output looks like this:
[
{
"id": "ethereum",
"name": "Ethereum",
"symbol": "ETH",
"rank": "2",
"price_usd": "95.3675",
"price_btc": "0.0605977",
"24h_volume_usd": "152223000.0",
"market_cap_usd": "8713986432.0",
"available_supply": "91372705.0",
"total_supply": "91372705.0",
"percent_change_1h": "0.38",
"percent_change_24h": "1.38",
"percent_change_7d": "37.07",
"last_updated": "1494105266"
}
]
Next I want to pull the "symbol" item from the JSON and return that back to the spreadsheet. In this case, the function would take in "Ethereum" and return "ETH".
Below is my code. Whenever I run it I get an error saying my name variable is undefined, resulting in a URL that looks like this (says "undefined" instead of "ethereum"):
https://api.coinmarketcap.com/v1/ticker/undefined/?convert=USD
What am I doing wrong?
function getSymbol (name) {
var url = "https://api.coinmarketcap.com/v1/ticker/"+name+"/?convert=USD";
var response = UrlFetchApp.fetch(url);
var text = response.getContentText();
var json = JSON.parse(text);
var sym = json["symbol"];
return sym;
}
The return type is an array of objects i.e. json = [{object1},{object2}]
Even though there is just one element, you still need to access it like so
var sym = json[0]["symbol"]
//or
var sym = json[0].symbol
Your final code will look like this:
function getSymbol (name) {
var url = "https://api.coinmarketcap.com/v1/ticker/"+name+"/?convert=USD";
var response = UrlFetchApp.fetch(url);
var text = response.getContentText();
var json = JSON.parse(text);
var sym = json[0]["symbol"];
return sym;
}

Resources