Using classes in firebase functions? - node.js

I am writing code for a firebase function, the problem is that I need to use a class but when I call the class method the firebase function log shows this error:
ERROR:
ReferenceError: Proverbi is not defined
at exports.getProverbio.functions.https.onRequest (/srv/index.js:48:26)
at cloudFunction (/srv/node_modules/firebase-functions/lib/providers/https.js:49:16)
at /worker/worker.js:783:7
at /worker/worker.js:766:11
at _combinedTickCallback (internal/process/next_tick.js:132:7)
at process._tickDomainCallback (internal/process/next_tick.js:219:9)
Here's the "index.js" code:
//firebase deploy --only functions
// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');
// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require('firebase-admin');
admin.initializeApp();
// Take the text parameter passed to this HTTP endpoint and insert it into the
// Realtime Database under the path /messages/:pushId/original
exports.addStanza = functions.https.onRequest(async (req, res) => {
// Grab the text parameter.
const nome = req.query.text;
// Push the new message into the Realtime Database using the Firebase Admin SDK.
const snapshot = await admin.database().ref('/stanze').push({giocatori: {giocatore:{nome:nome,punteggio:0}}});
// Redirect with 303 SEE OTHER to the URL of the pushed object in the Firebase console.
//res.redirect(200, nome.toString());
var link = snapshot.toString().split('/');
res.json({idStanza:link[4]});
});
// Listens for new messages added to /messages/:pushId/original and creates an
// uppercase version of the message to /messages/:pushId/uppercase
exports.addFirstPlayer = functions.database.ref('/stanze/{pushId}/giocatori/giocatore/nome')
.onCreate((snapshot, context) => {
// Grab the current value of what was written to the Realtime Database.
const nome = snapshot.val();
// const snapshot3 = snapshot.ref('/stanza/{pushId}/giocatori/giocatore').remove();
const snapshot2 = snapshot.ref.parent.parent.remove();
return snapshot.ref.parent.parent.push({nome:nome,punteggio:0});
});
exports.addPlayer = functions.https.onRequest(async (req, res) => {
// Grab the text parameter.
const nome = req.query.text;
const idStanza = req.query.id;
// Push the new message into the Realtime Database using the Firebase Admin SDK.
const snapshot = await admin.database().ref('/stanz/'+idStanza+"/giocatori").push({nome:nome,punteggio:0 });
// Redirect with 303 SEE OTHER to the URL of the pushed object in the Firebase console.
//res.redirect(200, nome.toString());
res.json({success:{id:idStanza}});
});
exports.getProverbio = functions.https.onRequest(async (req, res) => {
const difficolta = req.query.difficolta;
var proverbioClass = new Proverbi(2);
var p = proverbioClass.getProverbio();
var proverbio = p.split('-');
var inizio = proverbio[0];
var fine = proverbio[1];
res.json({proverbio:{inizio:inizio,fine:fine,difficolta:difficolta}});
});
Here's the code that's causing the problem:
exports.getProverbio = functions.https.onRequest(async (req, res) => {
const difficolta = req.query.difficolta;
var proverbioClass = new Proverbi(2);
var p = proverbioClass.getProverbio();
var proverbio = p.split('-');
var inizio = proverbio[0];
var fine = proverbio[1];
res.json({proverbio:{inizio:inizio,fine:fine,difficolta:difficolta}});
});
Here's the "Proverbi.class" code:
class Proverbi{
constructor(n) {
this.magicNumber = n;
}
getProverbio() {
var text = "";
switch (magicNumber) {
case 1:
text += ("Chip");
text += ("-Chop");
break;
}
return text;
}
}
How can I use the "Proverbi" class inside the "index.js"?

You need to add the definition of your Proverbi Class to the index.js file.
If you are just going to use this Class in the getProverbio Cloud Function, do as follows:
exports.getProverbio = functions.https.onRequest(async (req, res) => {
class Proverbi {
constructor(n) {
this.magicNumber = n;
}
getProverbio() {
var text = "";
switch (this.magicNumber) {
case 1:
text += ("Chip");
text += ("-Chop");
break;
}
return text;
}
}
const difficolta = req.query.difficolta;
var proverbioClass = new Proverbi(2);
var p = proverbioClass.getProverbio();
var proverbio = p.split('-');
var inizio = proverbio[0];
var fine = proverbio[1];
res.json({ proverbio: { inizio: inizio, fine: fine, difficolta: difficolta } });
});
If you want to use the Class in other functions, just declare it as follows:
class Proverbi {
constructor(n) {
console.log(n);
}
getProverbio() {
console.log(this.magicNumber);
console.log(this.magicNumber);
var text = "";
switch (this.magicNumber) {
case 1:
text += ("Chip");
text += ("-Chop");
break;
}
return text;
}
}
exports.getProverbio = functions.https.onRequest(async (req, res) => {
const difficolta = req.query.difficolta;
var proverbioClass = new Proverbi(2);
var p = proverbioClass.getProverbio();
var proverbio = p.split('-');
var inizio = proverbio[0];
var fine = proverbio[1];
res.json({ proverbio: { inizio: inizio, fine: fine, difficolta: difficolta } });
});

Related

BotFramework TypeError: Cannot perform 'get' on a proxy that has been revoked

I am trying to develop a MS Teams bot that sends content to students module(unit) wise. I have created 3 classes:
methods.js = Contains all the methods for sending texts, attachments etc.
teamBot.js = Captures a specific keyword from the users and based on that executes a function.
test.js = Connects the bot with Airtable and sends the content accordingly
I am facing Cannot perform 'get' on a proxy that has been revoked error. I figured it might be because of the context. I am passing context as a parameter, which I feel might not be the correct way, how can I achieve the result, and retain the context between files.
teamsBot.js
const test = require("./test");
class TeamsBot extends TeamsActivityHandler {
constructor() {
super();
// record the likeCount
this.likeCountObj = { likeCount: 0 };
this.onMessage(async (context, next) => {
console.log("Running with Message Activity.");
let txt = context.activity.text;
// const removedMentionText = TurnContext.removeRecipientMention(context.activity);
// if (removedMentionText) {
// // Remove the line break
// txt = removedMentionText.toLowerCase().replace(/\n|\r/g, "").trim();
// }
// Trigger command by IM text
switch (txt) {
case "Begin": {
await test.sendModuleContent(context)
}
// By calling next() you ensure that the next BotHandler is run.
await next();
});
// Listen to MembersAdded event, view https://learn.microsoft.com/en-us/microsoftteams/platform/resources/bot-v3/bots-notifications for more events
this.onMembersAdded(async (context, next) => {
const membersAdded = context.activity.membersAdded;
for (let cnt = 0; cnt < membersAdded.length; cnt++) {
if (membersAdded[cnt].id) {
const card = cardTools.AdaptiveCards.declareWithoutData(rawWelcomeCard).render();
await context.sendActivity({ attachments: [CardFactory.adaptiveCard(card)] });
break;
}
}
await next();
});
}
test.js
const ms = require('./methods')
async function sendModuleContent(context) {
data = module_text //fetched from Airtable
await ms.sendText(context, data)
}
methods.js
const {TeamsActivityHandler, ActivityHandler, MessageFactory } = require('botbuilder');
async function sendText(context, text){
console.log("Sending text")
await context.sendActivity(text);
}
Refer this: TypeError: Cannot perform 'get' on a proxy that has been revoked
make the following changes to test.js
const {
TurnContext
} = require("botbuilder");
var conversationReferences = {};
var adapter;
async function sendModuleContent(context) {
data = module_text //fetched from Airtable
const currentUser = context.activity.from.id;
conversationReferences[currentUser] = TurnContext.getConversationReference(context.activity);
adapter = context.adapter;
await adapter.continueConversation(conversationReferences[currentUser], async turnContext => {
await turnContext.sendActivity(data);
});
}

AWS lambda sending sns message to phone number

I have a lambda function running node.js The function makes database calls and sends a text message via sns. It has the following structure
the functions -> index.js file looks like this
async function sendTextMessage(message, phoneNumber) {
try {
console.log("hitSendFunction");
const sns = new AWS.SNS();
const params = {
Message: message,
MessageStructure: "string",
PhoneNumber: phoneNumber
};
//remember phone number must have +1 before it.
return await sns.publish(params).promise();
} catch (error) {
console.log(error);
}
}
module.exports = {
sendTextMessage
};
that function is than called in the main index.js file:
const database = require("./db");
const { sendTextMessage } = require("./functions");
const AWS = require("aws-sdk");
AWS.config.region = "us-east-1";
exports.handler = async function (event, context) {
try {
console.log("hit");
const result = await database.query("call getTicker()");
const data = result[0][0];
const currentProjectEndDate = new Date(
data.currentProjectEndDate
).getTime();
const now = new Date().getTime();
console.log("data.currentProjectEndDate", data.currentProjectEndDate);
const runningHot =
data.jobsInQueue > 0 && currentProjectEndDate <= now && data.textSent < 1;
if (runningHot) {
const numbers = ["+1435994****"];
for (let i = 0; i < numbers.length; i++) {
let number = numbers[i];
console.log("number", number);
let messageResult = await sendTextMessage(
"The CE Bot is running hot from lambda",
number
);
console.log("messageResult", messageResult);
}
await database.query("call insertIntoTextSent()");
console.log("yes");
}
} catch (error) {
console.log("this was the error", error);
}
The database calls work correctly but the textMessage function just hangs and times out. The lambda function has the following permissions attached to it:
Finally even though I do not think it is needed as the db code is working here is what the db -> index.js file looks like:
const mysql = require("mysql");
const util = require("util");
const awsConfig = {
host: process.env.RDS_HOST,
user: process.env.RDS_USER,
password: process.env.RDS_PASSWORD,
database: process.env.RDS_DATABASE
};
const connection = mysql.createConnection(awsConfig);
connection.query = util.promisify(connection.query.bind(connection));
connection.end = util.promisify(connection.end.bind(connection));
module.exports = connection;
I am not quite sure where I am going wrong here. Can someone point me in the right direction?
You can just send it via sms in sns just type in the phone number

Define variable global not local

I have some issues to use a global variable in my node.js app.
I use:
app.locals.isTestCafeRunning = false;
I think the problem here is locals, I think this variable is only valid inside the browser session, not inside the global app.
I want to use this variable in the main route:
app.get('/', function(req, res) {
async function getListData(){
var myListOptions = "";
var myListText = "";
arrayTestcaseData = await getMongojson();
/*code cut*/
var inPlaceButton = "";
if(req.app.locals.isTestCafeRunning===false){
inPlaceButton = "<button id=\"myButton\">Testrun starten</button>";
}else{
inPlaceButton = "<strong>Clipcafe in Benutzung!</strong>";
}
myHtmlCode = myHtmlCode.replace("%%BUTTON%%",inPlaceButton);
res.send(myHtmlCode);
}
getListData();
});
I want to fill the variable in
app.post('/clicked', (req, res) => {
//Function start Testcafe?
createTestCafe('localhost', 1337, 1338)
.then(tc => {
testcafe = tc;
const runner = testcafe.createRunner();
req.app.locals.isTestCafeRunning = true;
inputStore.clLogin = req.body.name;
inputStore.clPassword = req.body.pass;
inputStore.metaFolder = '19233456';
inputStore.metaUrl = req.body.channel;
return runner
.src(['tests/temp.js'])
.browsers(myBrowser)
//.browsers('browserstack:Chrome')
.screenshots('allure/screenshots/', true)
.reporter('allure')
.run();
})
.then(failedCount => {
req.app.locals.isTestCafeRunning = false;
console.log('Tests failed: ' + failedCount);
testcafe.close();
startReportGenerator();
res.sendStatus(201);
});
});
But I want to have this global not local vor all users, so if user 1 starts TestCafe, user 2 will only see "In use".

TypeError: contract.test is not a function tronweb nodejs

I am trying to access Tron smart contract which is deployed on the Shasta test network using Tron-Web. I am using node-casiko server Following is my code:
const TronWeb = require('tronweb')
// This provider is optional, you can just use a url for the nodes instead
const HttpProvider = TronWeb.providers.HttpProvider;
const fullNode = 'https://api.shasta.trongrid.io';
const solidityNode = 'https://api.shasta.trongrid.io';
const eventServer = 'https://api.shasta.trongrid.io';
const privateKey = 'my test account private key';
const tronWeb = new TronWeb(
fullNode,
solidityNode,
eventServer,
privateKey
);
module.exports = {
tmp: async function (req, res, next){
try{
var contract = await tronWeb.trx.getContract("TS71i14jzLawbtu4qPDKEsFERSp6CQb93948");
//res.send(contract)
var result = await contract.test().call();
//res.send(result);
}
catch(err){
console.error(err)
}
}
}
When I execute this js file using node having version v10.15.3. I am getting Error as:
TypeError: contract.test is not a function
at tmp (/home/administrator/node-Casiko/models/tronContract.js:25:32)
at process._tickCallback (internal/process/next_tick.js:68:7)
If I print the contract variable it is printing all information about the contract, but it is not calling the contract methods. Can somebody help me with this problem?
Well, I managed to find an answer for self-question. Just change the code as below. It works!!
module.exports = {
tmp: async function (req, res, next){
try{
var contract = await tronWeb.contract()
.at("TS71i14jzLawbtu4qPDKEsFERSp6CQb93948")
var result = await contract.test().call();
}
catch(err){
console.error(err)
}
}

Firebase Cloud Functions Cron Async Func Multiple Calls

I have a cloud function. It is triggered by an App Engine Cron job. It triggers my Firebase Cloud Function every hour with a Google Cloud Pub/Sub. I fetch my Firebase Realtime Database once, and loop for every value. The problem is my main.async function called multiple times. I use an i variable for loop and my console logs more i count than my database length. I mean that if my database length is 4, but for loop runs 8 or 15 or 23 times. This values change randomly. I want to loop for my each database value,fetch some data on internet,and when it is done, go for next value. Here is the code:
use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
var request = require('request-promise').defaults({ encoding: null });
var fs = require('fs');
// Get a reference to the Cloud Vision API component
const Vision = require('#google-cloud/vision');
const vision = new Vision.ImageAnnotatorClient();
var os = require("os");
var databaseArray = [];
var uniqueFilename = require('unique-filename')
exports.hourly_job = functions.pubsub
.topic('hourly-job')
.onPublish((event) => {
console.log("Hourly Job");
var db = admin.database();
var ref = db.ref("myData")
ref.once("value").then(function(allData) {
allData.forEach(function(deviceToken) {
deviceToken.forEach(function(firebaseIDs) {
var deviceTokenVar = deviceToken.key;
var firebaseIDVar = firebaseIDs.key;
var firstvalue = firebaseIDs.child("firstvalue").val();
var secondvalue = firebaseIDs.child("secondvalue").val();
var items = [deviceTokenVar, firebaseIDVar, firstvalue, secondvalue];
databaseArray.push(items);
});
});
return databaseArray;
}).then(function (databasem) {
main().catch(console.error);
});
return true;
});
const main = async () => {
var i;
for (i = 0; i < databaseArray.length; i++) {
console.log("Database Arrays " + i + ". elements: ");
if (databaseArrayfirst != "") {
var apiUrl = "http://api.blabla;
try {
const apiBody = await request.get(apiUrl);
///////////////////////////vison start//////////////////////
const visionResponseBody = await vision.documentTextDetection(apiBody)
var visionResponse = visionResponseBody[0].textAnnotations[0].description;
...some logic here about response...
/////////////////////////////////////////////////
var getdatabasevar = await admin.database().ref("myData/" + databaseArrayDeviceToken + "/" + databaseArrayFirebaseID);
await getdatabasevar.update({
"firstvalue": visionResponse
});
/////////////////////////////////////////////////
} catch (error) {
console.error(error);
}
///////////////////////////vison end//////////////////////
}
};
return true;
};
Thank you.

Resources