Delete user with redux-thunk in firebase - javascript

I want to delete a user from firebase. And my action is called from a button.
`
export const deleteAccount = () =>{
return async (dispatch, getState) =>{
const token =getState().auth.token;
let response;
try{
response = await fetch('https://identitytoolkit.googleapis.com/v1/accounts:delete?
key=[My_API_key]',
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
token:token
})
});
} catch(err){
throw new Error(err.message);
}
if(!response.ok){
const errorResData = await response.json();
console.log(errorResData);
const errorId = errorResData.error.message;
let message = 'Something went Wrong!';
if(errorId === 'INVALID_ID_TOKEN'){
message = 'Please Login Again!!'
} else if(errorId === "USER_NOT_FOUND"){
message = 'User Not Found';
}
throw new Error(message);
}
// dispatch(authentication(resData.localId, resData.idToken, parseInt(resData.expiresIn)*1000 ));
dispatch({type: DELETE});
}
};
`
on consoling my errorResData I am getting response
Object { "error": Object { "code": 400, "errors": Array [ Object { "domain": "global", "message": "MISSING_ID_TOKEN", "reason": "invalid", }, ], "message": "MISSING_ID_TOKEN", }, }
if I console my token I am getting that token.
Thanks in advance!!

I'm not entirely sure why you aren't using the Firebase SDK to do this, but you should be using v3 of the Identity Toolkit API.
await fetch(
"https://www.googleapis.com/identitytoolkit/v3/relyingparty/deleteAccount",
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
idToken: FRESH_USER_ID_TOKEN
})
}
);

Related

React / Node - PayPal can't capture a new subscription

I wan't to capture a new paypal subscription from frontend in my backend and give response with the needed data for mongodb.
If I add a body with capture_type: 'OUTSTANDING_BALANCE' (I found that in the manual) I'm getting this error.
So I'm not sure either it's just a wrong body or i totally mess up something else in the backend but so far I can't capture the subscription even so I get a subscription Id from
createSubscription Controller
PayPalScriptProvider
<PayPalScriptProvider options={initialOptions}>
<PayPalSubscriptionButton/>
</PayPalScriptProvider>
PayPal Button
{isPending ? <LoadingMedium /> : null}
<PayPalButtons
createSubscription={(data, actions) => {
return axios
.post(
'/api/subscription',
)
.then((response) => {
return response.data.id;
});
}}
onApprove={(data, actions) => {
axios
.post(`/api/subscription/${data.subscriptionID}/capture`)
.then(() => {
axios
.patch(
`/api/activesubscription`,
{
id: activeSub[0]?._id,
subscriptionID: data.subscriptionID,
}
)
});
});
}}
/>
Route for createSubscription
router.route('/subscription').post(async (req, res) => {
const searchPlan = await SubscriptionAmount.find();
console.log(searchPlan[0]?.subscriptionAmount);
const subscription = await paypalFee.createSubscription(
searchPlan[0]?.subscriptionAmount
);
res.json(subscription);
});
Router for onApprove
router.post('/subscription/:subscriptionID/capture', async (req, res) => {
const { subscriptionID } = req.params;
console.log('subscriptionID', subscriptionID);
const captureData = await paypalFee.captureSubscription(subscriptionID);
console.log('captureData', captureData);
res.json(captureData);
});
createSubscription Controller
async function createSubscription(planId) {
const accessToken = await generateAccessToken();
const url = `${base}/v1/billing/subscriptions`;
const response = await fetch(url, {
method: 'post',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${accessToken}`,
},
body: JSON.stringify({
intent: 'subscription',
plan_id: planId,
}),
});
const data = await response.json();
console.log('data', data);
return data;
}
captureSubscription Controller
async function captureSubscription(subscriptionId) {
const accessToken = await generateAccessToken();
const url = `${base}/v1/billing/subscriptions/${subscriptionId}/capture`;
const response = await fetch(url, {
method: 'post',
body: JSON.stringify({
// capture_type: 'OUTSTANDING_BALANCE',
}),
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${accessToken}`,
},
});
const data = await response.json();
console.log('data', data);
return data;
}
I'm getting this logs for my data in captureSubscription if I do not pass a body in my captureSubscription Controller:
captureData {
name: 'INVALID_REQUEST',
message: 'Request is not well-formed, syntactically incorrect, or violates schema.',
details: [
{
location: 'body',
issue: 'MISSING_REQUEST_BODY',
description: 'Request body is missing.'
}
]
}
With body I'm getting this error
captureData {
name: 'UNPROCESSABLE_ENTITY',
message: 'The requested action could not be performed, semantically incorrect, or failed business validation.',
details: [
{
issue: 'ZERO_OUTSTANDING_BALANCE',
description: 'Current outstanding balance should be greater than zero.'
}
],
}
ZERO_OUTSTANDING_BALANCE
There is no outstanding balance to capture. An outstanding balance occurs when payments are missed due to failures.
For ordinary (non-outstanding) subscription payments, no captures can be triggered. Subscriptions will capture automatically on the schedule you specify in the plan, that is the point of subscriptions.

Sapper $Session change not reflected until page reload

In my nav.svelte component I have:
{#if $session.token}
${JSON.stringify($session.token)} - ${JSON.stringify($session.token.username)}
{/if}
In login.svelte:
const { session } = stores();
let username, password;
async function onLogin(username, password){
const response = await fetch(`auth/login`, {
method:"POST",
headers:{ 'Content-Type': 'application/json' },
body: JSON.stringify({"username":username,"password":password})
})
if (response.ok) {
const json = await response.json();
session.set({ token: json });
$session.token = json;
goto("/");
} else {
throw new Error(response);
}
}
login.js handler:
req.session.token = user; //parsed.token;
console.log(`req.session.token: ${JSON.stringify(req.session.token)}`);
res.writeHead(200, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({ token: user }));
server.js:
sapper.middleware({
session: (req, res) => {
console.log(`% req.session.token: ${JSON.stringify(req.session.token)}`);
return ({
token: req.session.token
})}
})
The output in nav.svelte is:
${"token":{"_id":"kjbLgeU8k3GPr6jBd8NkCj","username":"matt123","password":"$2b$10$aXMJc64o9W166OL12CG/A.lWyuB9zdPkaNUsze3Lch6Z2khHaTKY.","access":"user"}} - $undefined
Notice that the data is there, but username outputs undefined. I believe I am doing something wrong but it is obscure.
Added an issue to the tracker on sapper project:
https://github.com/sveltejs/sapper/issues/1711

Issue with fetch: Getting type error failed to fetch

I'm trying to make a post call to the backend server, but I keep running into this error:
TypeError: Failed to fetch
I've looked over the code a bunch of times but can't seem to find the issue. Here is the code:
async doLogin() {
if(!this.state.email || !this.state.password) {
return
}
this.setState({
buttonDisabled : true
})
try {
let res = await fetch('/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: this.state.email,
password: this.state.password
})
})
console.log(res)
let result = await res.json()
console.log(result)
if(result && result.success) {
UserStores.isLoggedIn = true
UserStores.email = result.email
alert(result.msg)
} else if(result && result.success === false) {
this.resetForm()
alert(result.msg)
}
} catch(e) {
console.log('doLogin error: ', e)
this.resetForm()
}
}
This is an example response payload:
{
"success": true,
"email": "mfultz956#gmail.com",
"msg": "Login Verified!"
}
Login Call - Network Tab
Login Call - Headers
change it to :
let res = await fetch('http://localhost:your_api_server_port/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: this.state.email,
password: this.state.password
})
})

Async/Await in fetch() how to handle errors

I have stripe async code in my React app, and trying to add error handling in my code but have no idea how to handle it. i know how to do it with .then() but async/await is new to me
EDITED
added .catch() i got errors in network tab in response tab.
but i can log it to console?
submit = async () => {
const { email, price, name, phone, city, street, country } = this.state;
let { token } = await this.props.stripe
.createToken({
name,
address_city: city,
address_line1: street,
address_country: country
})
.catch(err => {
console.log(err.response.data);
});
const data = {
token: token.id,
email,
price,
name,
phone,
city,
street,
country
};
let response = await fetch("/charge/pay", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
}).catch(err => {
console.log(err.response.data);
});
console.log(response);
if (response.ok)
this.setState({
complete: true
});
};
thanks
Fetch detects only network errors. Other errors (401, 400, 500) should be manually caught and rejected.
await fetch("/charge/pay", headers).then((response) => {
if (response.status >= 400 && response.status < 600) {
throw new Error("Bad response from server");
}
return response;
}).then((returnedResponse) => {
// Your response to manipulate
this.setState({
complete: true
});
}).catch((error) => {
// Your error is here!
console.log(error)
});
If you are not comfortable with this limitation of fetch, try using axios.
var handleError = function (err) {
console.warn(err);
return new Response(JSON.stringify({
code: 400,
message: 'Stupid network Error'
}));
};
var getPost = async function () {
// Get the post data
var post = await (fetch('https://jsonplaceholder.typicode.com/posts/5').catch(handleError));
// Get the author
var response = await (fetch('https://jsonplaceholder.typicode.com/users/' + post.userId).catch(handleError));
if (response.ok) {
return response.json();
} else {
return Promise.reject(response);
}
};
You can either use try/catch just like normal, imperative programming:
try {
let response = await fetch("/charge/pay", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
});
} catch(error) {
// Error handling here!
}
Or you can mix-and-match .catch() just like you do with promises:
let response = await fetch("/charge/pay", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
}).catch(function(error) {
// Error handling here!
});
Wrap your await with try catch.
try {
let response = await fetch("/charge/pay", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
});
console.log(response);
} catch (error) {
console.log(error);
}
This works if server returns { message: "some error" } but I'm trying to get it to support res.statusText too:
const path = '/api/1/users/me';
const opts = {};
const headers = {};
const body = JSON.stringify({});
const token = localStorage.getItem('token');
if (token) {
headers.Authorization = `Bearer ${token}`;
}
try {
const res = await fetch(path, {
method: opts.method || 'GET',
body,
headers
});
if (res.ok) {
return await (opts.raw ? res.text() : res.json());
}
const err = await res.json();
throw new Error(err.message || err.statusText);
} catch (err) {
throw new Error(err);
}
async function loginWithRedirect(payload: {
username: string;
password: string;
}) {
const resp = await (await fetch(`${env.API_URL}/api/auth/login`, {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify(payload),
credentials: "include",
})).json();
if (resp.error) {
dispatch({type: "ERROR", payload: resp.error.message});
} else {
dispatch({type: "LOGIN", payload: resp});
}
}
If response.ok is false you can throw an error then chain catch method after calling your function as follows
async function fetchData(){
const response = await fetch("/charge/pay", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
});
if(!response.ok){
const message = `An error occured: ${response.status}`;
throw new Error(message);
}
const data = await response.json();
return data;
}
fetchData()
.catch(err => console.log(err.message));
I write promise function for using fetch in async await.
const promisyFetch = (url, options) =>
new Promise((resolve, reject) => {
fetch(url, options)
.then((response) => response.text())
.then((result) => resolve(result))
.catch((error) => reject(error));
});
By the way i can use it easly in async with try catch
const foo = async()=>{
try {
const result = await promisyFetch('url' requestOptions)
console.log(result)
} catch (error) {
console.log(error)
}
}
It was simple example, you could customize promisyFetch function and request options as you wish.
const data = {
token: token.id,
email,
price,
name,
phone,
city,
street,
country
};
axios
.post("/charge/pay", data)
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err.response.data);
});

How use await keyword along with asyncstorage setitem for server response?

I'm trying to use asyncstorage in my react native app.The problem is the server response I'm getting takes some delay so I want to wait for the response then I want to use that responseData.user_id to be saved in my app.I'm using nodejs as backend and mysql db.So after user registration I'm inserting it to db at the same time I've written another query for fetching their user_id (PK).So this responseData is getting to client and I'm trying to take that user_id from the response.So I've written something like this
onPressRegister = async () => {
try {
let response = await fetch('http://192.168.1.2:3000/users/registration', {
method: 'POST',
headers: {
'Accept': 'applictaion/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
contact: this.state.contact,
password: this.state.password,
})
});
let responseData = await response.json();
if (responseData) {
try {
Action.firstScreen();
await AsyncStorage.setItem('userid', JSON.stringify(responseData.userData.phone_no));
}
catch (e) {
console.log('caught error', e);
}
}
} catch (error) {
console.error(error)
}
}
And in my next screen I'm accessing the userid like this.And passing it the next API call like this.
getUserId = async () => {
let userId = await AsyncStorage.getItem('userid');
return userId;
}
onPressYes = (workType) => {
this.getUserId().then((userId) => {
this.setState({userId:userId})
})
fetch('http://192.168.1.2:3000/users/user_request',{
method:'POST',
headers:{
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
workType,
phone:this.state.userId
})
})
.then(response => response.json())
.then((responseData) => {
this.setState({
data:responseData
});
});
}
But this is the error I'm getting.
Try this:
onPressRegister = async () => {
try {
let response = await fetch('http://192.168.1.6:3000/users/registration', {
method: 'POST',
headers: {
'Accept': 'applictaion/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
contact: this.state.contact,
password: this.state.password,
})
});
let responseData = await response.json();
if (responseData) {
try {
await AsyncStorage.setItem('userid', JSON.stringify(responseData.user_id));
}
catch (e) {
console.log('caught error', e);
}
}
} catch (error) {
console.error(error)
}
}
To access the value in some other component:
getUserId = async () => {
let userId = await AsyncStorage.getItem('userid');
return userId;
}
componentWillMount() {
this.getUserId().then((userId) => {
console.log(userId);
})
}

Categories

Resources