How To make a post request from react to node/express api - javascript

All i need to do is to send my state of invoice details to database through post request but im having troubles doing it is this the right way to do it or am i missing something
post function works fine if the query is only a string so the only problem is reading the body params
const postInvoices = () => {
const URL = "http://localhost:8000/api/InvSave";
axios
.post(URL,InvDet)
.then((response) => {
console.log("DATA : ",response);
})
.catch((error) => {
console.log(error);
});
};
im sending the state on click
in my api i wrote :
router.route('/InvSave').post((request,response)=>{
try{
const invoices = request.body
dboperations.PostInvoices(invoices).then(result => {
response.status(201).json("api results :",result);
})
}catch(err){
console.error(err)
}
})
const PostInvoices = async (invoices) => {
try {
let pool = await sql.connect(configInsert);
console.log("invoices code",CODE_ART)
const q =
"insert into Packingdetails values('1','"+
invoices.CODE_ART +
"','" +
invoices.a_code +
"','" +
invoices.DESC_ART +
"','" +
invoices.TotalPc +
"','" +
invoices.date+
"')";
console.log("query : "+q)
let invs = await pool.query(q);
console.log("saved");
return invs.recordsets;
} catch (err) {
console.log("POSTINV : ", err.message);
}
};

make sure you are using some kind of body-parser to parse your request
console.log(invoices) to check if you are getting the correct invoices in request body

Related

using .then nodejs

I have a large function that says, okay add this employee to the db based on what the admin entered. But now I need to check, does this user already exist in the db. so I created a function that does just that called getEmployeeNum, but I need to perform a .then in the main function of /addEmployee to say, see what the result of the function getEmployeeNum is before you perform any of the other requests. see the code below:
app.post('/addEmployee', (req, res) => {
if (req.session.loggedin) {
var firstname = req.body.firstname;
var lastname = req.body.lastname;
var username = req.body.username;
var sales = req.body.sales;
var salary = req.body.salary;
var location = req.body.location;
var role = req.body.role;
var admin = req.body.admin;
var employeenum = req.body.employee_num;
var phonenum = req.body.phone_num;
var org = req.body.org;
var pass = "";
var newPassword = req.body.password
getEmployeeNum(req, res, employeenum)
bcrypt.hash(newPassword, saltRounds, function(err, hash) {
pass = hash
addLogin(req, res, pass, firstname, lastname, username, sales, salary, location, role, admin, employeenum, phonenum)
});
var addEmployee = "insert into EMPLOYEES (FIRSTNAME, LASTNAME, USERNAME, SALES, SALARY, LOCATION, ROLE, ADMIN, EMPLOYEE_NUM, PHONENUM, ORGANIZATION) VALUES ('" +
req.body.firstname +
"', '" +
req.body.lastname +
"', '" +
req.body.username +
"', '" +
req.body.sales +
"', '" +
req.body.salary +
"', '" +
req.body.location +
"', '" +
req.body.role +
"', '" +
req.body.admin +
"', '" +
req.body.employee_num +
"', '" +
phonenum +
"', '" +
org +
"' )";
ibmdb.open(ibmdbconnMaster, function(err, conn) {
if (err) return console.log(err);
conn.query(addEmployee, function(err, rows) {
if (err) {
console.log(err);
}
registerEmail(username, firstname, lastname, req, res)
res.redirect('/employees')
})
})
} else {
res.render('login.ejs')
}
})
function getEmployeeNum(req, res, employeenum) {
var getEmployeeNum = "select * from employees"
ibmdb.open(ibmdbconnMaster, function(err, conn) {
if (err) return console.log(err);
conn.query(getEmployeeNum, function(err, rows) {
if (err) {
console.log(err);
}
for (var i = 0; i < rows.length; i++) {
var employee_num = rows[i]["EMPLOYEE_NUM"]
if (employeenum == employee_num) {
alert("employee already exists")
res.render("addEmployee.ejs")
}
}
conn.close(function() {
// console.log("closed the function /index");
});
});
})
}
is this the right way to do it, or is there a better way? Thanks :)
I see that you're using the callback version of SQL driver. I'll assume that you;re working with mysql2 for simplicity wise.
There is actually a promise version of mysql2 driver
const mysql = require('mysql2/promise');
I'll share with you some of the common patterns I use when working with DB.
// Create a pool for connection
const pool = mysql.createPool({
connectionLimit: process.env.SQL_CON_LIMIT,
host: process.env.SQL_SERVER,
port: process.env.SQL_PORT,
user: process.env.SQL_USERNAME,
password: process.env.SQL_PASSWORD,
database: process.env.SQL_SCHEME,
timezone: process.env.SQL_TIMEZONE,
});
// To use async to test the connection via conn.ping() before launch server
const p1 = (async () => {
const conn = await pool.getConnection();
await conn.ping();
conn.release();
return true;
})();
// test connection for SQL, add other into array as you like
Promise.all([p1])
.then(() => {
app.listen(PORT, () =>
console.info(
`Application started on port http://localhost:${PORT}/ at ${new Date()}`
)
);
})
.catch((err) => {
console.error('Cannot connect: ', err);
});
The code block above is for setting up, and test connection before starting the server. This can avoid the rare case where DB is not initialized before the request came in (As the server can start before connecting to DB)
const makeQuery = (query, pool) => {
return async (args) => {
const conn = await pool.getConnection();
try {
let results = await conn.query(query, args || []);
return results[0]; // Result of query is in index 0
} catch (error) {
console.log(error);
} finally {
conn.release();
}
};
};
// Sample query
const queryCheckLogin =
'SELECT COUNT(*) as "match" FROM user WHERE user_id = ? AND password = ?';
// Make it into function!
const checkLogin = makeQuery(queryCheckLogin, pool);
app.post('/api/login', async (req, res) => {
let { user_id, password } = req.body;
// Obtain sha1 password from submitted password
password = sha1(password);
try {
let results = await checkLogin([user_id, password]);
// Return the credential (supposedly token) when record is matched
if (results[0]['match'] !== 0) {
res.status(200).json({ login: 'success', user_id, password });
} else {
// return 401 if record not found
res.status(401).json({ error: 'No such username or password' });
}
} catch (error) {
console.log(error);
res.status(400).json(error);
}
});
The code block above shows the factory function to deal with the general form of getting the result from a query, so you won't clutter the logic in middleware. So you will write out whatever query you will do, make it into function via makeQuery, and just use the resulting function.
Using async...await will also make the code cleaner, however, this depends on the version of codebase you're working on. However, the sample above do works for .then as well.

How do you trigger cloud functions when someone follows someone else using Firebase? I'm using Atom and Xcode

I'm using Firebase and I want to trigger a notification when 'person A' follows 'person B'.
This is my code:
exports.observeFollowing = functions.database.ref('/added/{followerID}/{followingID}').onCreate((snapshot, context) => {
var followerID = context.params.followerID;
var followingID = context.params.followingID;
console.log('User: ' + followerID + ' is following: ' + followingID);
//trying to figure out fcmtoken to send a notification
return admin.database().ref('/users/' + followingID).once('value', snapshot => {
var userWeAreFollowing = snapshot.val();
return admin.database().ref('/users/' + followerID).once('value', snapshot => {
var userDoingTheFollowing = snapshot.val();
var payload = {
notification: {
title: "Someone added you as a friend",
body: userDoingTheFollowing.username + ' is now following you'
}
}
return admin.messaging().sendToDevice(userWeAreFollowing.fcmToken, payload)
.then(response => {
console.log("Successfully sent message:", response);
return response
}).catch(function(error) {
console.log("Error sending message:", error);
});
})
})
});
The console prints the ('User: ' + followerID + ' is following: ' + followingID) part but doesn't show the notification. I've tested cloud notifications before and they worked but this doesn't work for some reason. In the logs, it says:
Successfully sent message: { results: [ { error:
[FirebaseMessagingError] } ]," "failureCount: 1," "successCount: 0,"
So I know that everything up until the console.log('User: ' + followerID + ' is following: ' + followingID); works. But I'm not sure if the notification function is even being called. Am I missing a semicolon or something else? I really can't figure it out. Also, what does failureCount mean? Is it talking about the notifications function?
As explained in the Cloud Functions doc, you need to manage the asynchronous Firebase operations by using promises. You are using the callback version of the once() method: you need to use the promise version, as follows:
exports.observeFollowing = functions.database.ref('/added/{followerID}/{followingID}').onCreate((snapshot, context) => {
const followerID = context.params.followerID;
const followingID = context.params.followingID;
let userWeAreFollowing;
console.log('User: ' + followerID + ' is following: ' + followingID);
return admin.database().ref('/users/' + followingID).once('value')
.then(snapshot => {
userWeAreFollowing = snapshot.val();
return admin.database().ref('/users/' + followerID).once('value')
})
.then(snapshot => {
const userDoingTheFollowing = snapshot.val();
const payload = {
notification: {
title: "Someone added you as a friend",
body: userDoingTheFollowing.username + ' is now following you'
}
}
return admin.messaging().sendToDevice(userWeAreFollowing.fcmToken, payload)
}).catch(function (error) {
console.log("Error sending message:", error);
return null;
});
});
If you want to log a message in the console upon success do as follows:
// ...
.then(snapshot => {
const userDoingTheFollowing = snapshot.val();
const payload = {
notification: {
title: "Someone added you as a friend",
body: userDoingTheFollowing.username + ' is now following you'
}
}
return admin.messaging().sendToDevice(userWeAreFollowing.fcmToken, payload)
})
.then(response => {
console.log("Successfully sent message:", response);
return null;
}).catch(function (error) {
console.log("Error sending message:", error);
return null;
});

Firebase cloud messaging function returning undefined

I'm simply sending a notification when someone new has followed you, but when I try to return the users username in the notification it just says "undefined has decided to follow you" instead of the username.
exports.observeFollowing = functions.database.ref('/following/{uid}/{followingId}').onCreate((snapshot,context) => {
var uid = context.params.uid;
var followingId = context.params.followingId;
console.log('User: ' + uid + 'is following: ' + followingId);
return admin.database().ref('/users/' + followingId).once('value', snapshot => {
var userWeAreFollowing = snapshot.val();
return admin.database().ref('/users/' + uid).once('value', snapshot => {
var userDoingTheFollowing = snapshot.val();
var payload = {
notification: {
title: "Someone new has followed you",
body: userWeAreFollowing.username + " has decided to follow you...",
sound: 'default'
}
}
admin.messaging().sendToDevice(userWeAreFollowing.fcmToken, payload)
.then((response) => {
console.log('Successfully sent message:', response);
return response
})
.catch((error) => {
console.log('Error sending message:', error);
});
})
})
Instead of
body: userWeAreFollowing.username + " has decided to follow you...",
should't be the following user name
body: userDoingTheFollowing.usernames + " has decided to follow you...",
and notice in your realtime database you saved the username as usernameS, that might be the problem

Sending notifications when button clicked errors

I'm trying to notify my users when someone clicks the going button but I keep getting a couple of errors in my firebase functions logs.
Uncaught Exception &
Registration token(s) provided to sendToDevice() must be a non-empty string or a non-empty array
exports.observeGoing = functions.database.ref('/going/{postId}/{uid}').onCreate((snapshot,context) => {
var postId = context.params.postId;
var uid = context.params.uid;
console.log('User: ' + uid + ' is going to your activity');
return admin.database().ref('/users/' + uid).once('value', snapshot => {
var creatorOfPost = snapshot.val();
admin.database().ref('/users/' + uid).once('value', snapshot => {
var userGoing = snapshot.val();
var payload = {
notification: {
body: userGoing.usernames + " is going",
sound: "default"
}
}
admin.messaging().sendToDevice(creatorOfPost.fcmToken, payload)
.then((response) => {
console.log('Successfully send message:', response);
return response
})
.catch((error) =>{
console.log('Error sending message:', error);
});
})
})
})
You reveive that error because creatorOfPost.fcmToken can be null
According to the firebase document, the first parameter of admin.messaging.Messaging.sendToDevice() cannot be null.
But in your code, there are 2 possibility to violate this precondition.
creatorOfPost.fcmToken can be null
just do null check before calling admin.messaging.Messaging.sendToDevice()
creatorOfPost can be null
firebase.database.Reference.once() returns DataSnapshot, but it doesnt mean there always be corresponding document.
so, var creatorOfPost = snapshot.val(); can be null.
maybe you can check like this:
return admin.database().ref('/users/' + uid).once('value', snapshot => {
if (!snapshot.exists()) {
return; // or do what you would like
}
var creatorOfPost = snapshot.val();
// ...
// ...
})

Send a POST request via Axios to a Firebase Cloud Function

I try to send a simple request to a Firebase function, but I get the same error every time... Apparently, the Firebase function does not receive the data I want to transmit from the Axios request.
This is the Firebase function :
[...] // Some imports
exports.completeProfile = functions.https.onRequest((req, res) => {
// Debug
console.log(req);
console.log(req.body);
console.log(req.method);
console.log("Test: " + userId + ", " + profilePicture + ", " + username);
// We recover the data
const userId = req.body.userId; // return "undefined"
const profilePicture = req.body.profilePicture; // return "undefined"
const username = req.body.username; // return "undefined"
// we're checking to see if they've been transferred
if (!userId || !profilePicture || !username) {
// At least one of the 3 required data is not completed
console.error("Error level 1: missing data");
return res.status(400).send("Error: missing data");
}
[...] // (We have all the data, we continue the function)
});
And here is my Axios request :
axios
.post(
'<FIREBASE CLOUD FUNCTION URL>',
{
userId: '12345667',
profilePicture: 'https://profilepicture.com/url',
username: 'test',
}
)
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
});
When I run the Axios query, I always come across the "Network Error" error. Here is what console.log(error); gives :
And here are the server logs:
How to solve the problem? Thanks for your help.
change your firebase code to this
var cors = require("cors");
completeProfileFn = (req, res) => {
// Debug
console.log(req);
console.log(req.body);
console.log(req.method);
console.log("Test: " + userId + ", " + profilePicture + ", " + username);
// We recover the data
const userId = req.body.userId; // return "undefined"
const profilePicture = req.body.profilePicture; // return "undefined"
const username = req.body.username; // return "undefined"
// we're checking to see if they've been transferred
if (!userId || !profilePicture || !username) {
// At least one of the 3 required data is not completed
console.error("Error level 1: missing data");
return res.status(400).send("Error: missing data");
}
// (We have all the data, we continue the function)
};
// CORS and Cloud Functions export logic
exports.completeProfile = functions.https.onRequest((req, res) => {
var corsFn = cors();
corsFn(req, res, function() {
completeProfileFn(req, res);
});
});
It is a CORS issue.

Categories

Resources