Cloud Function returns undefiend when using POST - javascript

I am trying to send the param name in the Cloud Function managed by Firebase using POST method, I've read quite a few documentation, and no matter what I try it always returns undefined. Also is it safe to use this for sensitive data?
Client-Side
fetch(`https://<<APP-NAME>>.cloudfunctions.net/addCardForExistingCustomer`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
JSON.stringify(body: {'name': 'Name'})
})
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(err => console.error(err));
Server-side (Firebase Cloud-Functions)
exports.addCardForExistingCustomer = functions.https.onRequest(async (request, response) => {
let name = await request.body.name
response.json({
response: `${name}`
})
})

Related

cannot get XSRF-TOKEN from cookie in nextjs (Reactjs)

I create a login form using Nextjs and backend with Laravel 8, I generate an XSRF-TOKEN in Laravel then set it on cookie, I can see the token inside inspect element> application tab> cookie section, but I can't set it on my fetch request to make my login, I using redux to store my data such: products, auth, cart and etc
AuthAction.js code:
export const LOGIN_AUTH = "LOGIN_AUTH";
export const LOGOUT_AUTH = "LOGOUT_AUTH";
export const HandleLogin = (data) => {
return async (dispatch, getState) => {
const getCsrf = await fetch("http://localhost:8000/sanctum/csrf-cookie");
if (!getCsrf.ok) {
throw new Error("Faild to set csrf token");
}
console.log("getCsrf", cookie.load("XSRF-TOKEN"));
const response = await fetch("http://localhost:8000/api/app/user/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
});
if (!response.ok) {
throw Error("Login faild");
}
try {
const responseData = await response.json();
console.log("login", responseData);
dispatch({
type: LOGIN_AUTH,
user: responseData,
});
} catch (err) {
console.log("Login err", err);
throw err;
}
};
};
after console.log("getCsrf", cookie.load("XSRF-TOKEN")); nothing happened.
what do I do wrong in my code?
cookie screenshot:
request response:
Use axios instead of fetch.
Example:
axios
.get("http://localhost:8000/sanctum/csrf-cookie", {
withCredentials: true,
})
.then((response) => {
axios("http://localhost:8000/api/app/user/login", {
method: "post",
data: data,
withCredentials: true,
})
.then((response) => {
console.log("login", response.data);
})
.catch((error) => {
console.log(error);
});
})
.catch((error) => {
// handle error
console.log(error);
})
.then(() => {
//
});
Since your next.js and laravel apps are on different origins, you need to set fetch to explicitly send cookies.
const response = await fetch("http://localhost:8000/api/app/user/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
credentials: 'include'
});
You can read more about the credentials property in the MDN docs
Also, you can read the cookie in the front-end if it's http-only cookie.
Also, don't forget to set up Cross origin resource sharing in your backend app.

Getting API authentication key error with PublicAPI

I'm new to the FetchAPAI. For my first API project, I'm currently using the ClimatIQ API and following the steps in their Quickstart guide. Even if I've already signed up and received an authentication key from them, I keep getting the ff error from them:
POST https://beta2.api.climatiq.io/estimate 400
{error: 'invalid_request', message: 'Error parsing the request body.'}
Take note in the guide, the code is in Curl, and I did my best trying to convert that code into a fetchAPI request on JavaScript.
const fetchData = async (url) => {
await fetch(url, {
method: "POST",
headers: { Authorization: "Bearer MY_API_KEY" },
data: {
emission_factor: "electricity-energy_source_grid_mix",
parameters: {
energy: 4200,
energy_unit: "kWh",
},
},
//body: JSON.stringify(data),
})
.then((response) => response.json())
.then((json) => console.log(json))
.catch((err) => console.log(`Here's the error ${err}`));
};
fetchData("https://beta2.api.climatiq.io/estimate");
From time to time, it also shows a "header is not defined" even if I already put in the authentication key they gave me in the "MY_API_KEY" part of my codebase. Is this an error with their server?
try this:
const data = {
emission_factor: "electricity-energy_source_grid_mix",
parameters: {
energy: 4200,
energy_unit: "kWh",
},
};
const fetchData = async(url) => {
await fetch(url, {
method: "POST",
headers: {
Authorization: "Bearer MY_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify(data)
})
.then((response) => response.json())
.then((json) => console.log(json))
.catch((err) => console.log(`Here's the error ${err}`));
};
fetchData("https://beta2.api.climatiq.io/estimate");

Res.send not a function

I have an endpoint (using express) which requires me to do some fetching first. Once a parse the response and use res.send I get an error res.send is not a function.
I tried searching for this error but all searches show users had res,req in the wrong order. In this case, mine appear to be right.
Why is it res is not scope after a convert my response to JSON?
router.post("/customerID", async (req, res) => {
return fetch({endPoint}, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Flowspace-Auth": {myToken},
},
body: JSON.stringify({
query: `query {
user {
name
organizationId
}
}`,
}),
})
.then((res) => {
res.json().then((data) => {
console.log(data) // This works
res.send({ data: data }); // res.send is not a function... why, is it not scoped correctly?
});
})
.catch((err) => console.log("unable to fetch:", err));
});
Your outer response variable is overwritten by your inner result variable. JS goes from the inner most scope to outer most looking for variable. Since, res is already defined in the then clause, that res is used.
Changing it to resp should work.
router.post("/customerID", async (req, resp) => {
return fetch({endPoint}, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Flowspace-Auth": {myToken},
},
body: JSON.stringify({
query: `query {
user {
name
organizationId
}
}`,
}),
})
.then((res) => {
res.json().then((data) => {
console.log(data) // This works
resp.send({ data: data }); // resp will belong to outer response
});
})
.catch((err) => console.log("unable to fetch:", err));
});
You probably want to send something in the catch part too.
You are calling send method on the response of the fetch api call on which the send method is not available. find the correct code below.
router.post("/customerID", async (req, res) => {
return fetch(
{ endPoint },
{
method: "POST",
headers: {
"Content-Type": "application/json",
"Flowspace-Auth": { myToken },
},
body: JSON.stringify({
query: `query {
user {
name
organizationId
}
}`,
}),
}
)
.then((response) => {
response.json().then((data) => {
console.log(data); // This works
res.send({ data: data });
});
})
.catch((err) => console.log("unable to fetch:", err));
});

Accessing promise data from Node API inside React fetch call

I'm putting together a React app that consumes data from a Node/Express REST API which is currently on my local machine. I've got a simple res.json returning a Sequelize object, and I'm accessing it through a service I made. Obviously, I'm going to be putting the object in state eventually, but I'm currently having difficulty accessing the values.
const options = {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: JSON.stringify({email: "matthewharp#gmail.com", password: "M1nerals"})
};
fetch('http://localhost:3000/users/sign_in', options)
.then(response => console.log(response.json()));
I'm getting the results in the console, but they're stuck in the [[PromiseValue]].
I must be missing some kind of async step, but I'm not sure what.
The json method returns a promise, which you also need to await. So do:
fetch('http://localhost:3000/users/sign_in', options)
.then(response => response.json())
.then(obj => console.log(obj));
You're having this error because response.json() return a promise.
you need to do
fetch('http://localhost:3000/users/sign_in', options)
.then(response => response.json())
.then(res => console.log(res));
You need to return the promise from the fetch call or else you need to act on it in the then for the json promise.
const options = {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: JSON.stringify({email: "matthewharp#gmail.com", password: "M1nerals"})
};
return fetch('http://localhost:3000/users/sign_in', options)
.then(response => {
console.log(response.json())
return response.json()
}
);
or...
const options = {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: JSON.stringify({email: "matthewharp#gmail.com", password: "M1nerals"})
};
fetch('http://localhost:3000/users/sign_in', options)
.then(response => {
console.log(response.json())
response.json().then( result => {
// whatever you're doing with the data here.
}
);
Take a look at the fetch api:
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
You need a separate then chained to take the json data once ready, and it will give you the values.
('http://localhost:3000/users/sign_in', options)
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(JSON.stringify(myJson));
});

Node Fetch Post Request using Graphql Query

I'm trying to make a POST request with a GraphQL query, but it's returning the error Must provide query string, even though my request works in PostMan.
Here is how I have it running in PostMan:
And here is the code I'm running in my application:
const url = `http://localhost:3000/graphql`;
return fetch(url, {
method: 'POST',
Accept: 'api_version=2',
'Content-Type': 'application/graphql',
body: `
{
users(name: "Thomas") {
firstName
lastName
}
}
`
})
.then(response => response.json())
.then(data => {
console.log('Here is the data: ', data);
...
});
Any ideas what I'm doing wrong? Is it possible to make it so that the body attribute I'm passing in with the fetch request is formatted as Text like I've specified in the PostMan request's body?
The body is expected to have a query property, containing the query string. Another variable property can be passed as well, to submit GraphQL variables for the query as well.
This should work in your case:
const url = `http://localhost:3000/graphql`;
const query = `
{
users(name: "Thomas") {
firstName
lastName
}
}
`
return fetch(url, {
method: 'POST',
Header: {
'Content-Type': 'application/graphql'
}
body: query
})
.then(response => response.json())
.then(data => {
console.log('Here is the data: ', data);
...
});
This is how to submit GraphQL variables:
const query = `
query movies($first: Int!) {
allMovies(first: $first) {
title
}
}
`
const variables = {
first: 3
}
return fetch('https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr', {
method: 'post',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({query, variables})
})
.then(response => response.json())
.then(data => {
return data
})
.catch((e) => {
console.log(e)
})
I created a complete example on GitHub.

Categories