How can I send fcmtoken to the api body? - javascript

When useEffect is executed in my code, I want to get fcmtoken through firebase .getToken and send fcmtoken to body of auth/me router.
but if i use my code this error occure
Unhandled Promise Rejection (id: 0):
ReferenceError: fcmtoken is not defined
Perhaps the cause of the error is incorrect use of async await or anything
but how can i fix my code?
this is my code
useEffect(() => {
Linking.addEventListener('url', async ({url}) => {
var newURL = url;
var splitURL = newURL.toString().split('=');
const token = splitURL[1];
messaging()
.getToken()
.then((fcmtoken) => {
return fcmtoken;
});
const {data} = await axios.post(
'/auth/me',
{fcmtoken},
{
headers: {Authorization: `Bearer ${token}`},
},
);
console.log('data::::', data);
AsyncStorage.setItem('tokenstore', `${token}`, () => {
console.log('유저 닉네임 저장 완료');
});
dispatch({
type: KAKAOLOG_IN_REQUEST,
data: data,
});
});
return () => Linking.removeEventListener('url');
}, []);

you are trying to send an undefined variable 'fcmtoken' to the API. In the code bellow I changed the way you get the fcm token.
useEffect(() => {
Linking.addEventListene`enter code here`r('url', async ({url}) => {
var newURL = url;
var splitURL = newURL.toString().split('=');
const token = splitURL[1];
let fcmtoken = await messaging().getToken();
const {data} = await axios.post(
'/auth/me',
{fcmtoken},
{
headers: {Authorization: `Bearer ${token}`},
},
);
console.log('data::::', data);
AsyncStorage.setItem('tokenstore', `${token}`, () => {
console.log('유저 닉네임 저장 완료');
});
dispatch({
type: KAKAOLOG_IN_REQUEST,
data: data,
});
});
return () => Linking.removeEventListener('url');
}, []);

Related

baseQueryWithReauth not handling 401 errors, also noticed the prepareHeaders returns an empty object

const baseQuery = fetchBaseQuery({
baseUrl: 'url',
prepareHeaders: (headers, { getState }) => {
const token = getState().auth.token
// If we have a token set in state, let's assume that we should be passing it.
if (token) {
headers.set('authorization', `Bearer ${token}`)
}
return headers
}
})
const baseQueryWithReauth = async (args, api, extraOptions) => {
let result = await baseQuery(args, api, extraOptions)
if (result?.error?.originalStatus === 401) {
//I noticed result.error.originalStatus always returned undefine
console.log('sending refresh token')
const refreshResult = await baseQuery({
url: '/users/generateTokens',
method: 'POST'
}, api, extraOptions)
console.log(refreshResult)
if (refreshResult?.data) {
const user = api.getState().auth.user
api.dispatch(setCredits({ ...refreshResult.data, user }))
result = await baseQuery(args, api, extraOptions)
console.log(result)
} else {
api.dispatch(logOut())
}
}
return result
}

React Native - Variable does not update correctly when retrieving data from AsyncStorage

I'm trying to store and get data that I fetch from an API. The user is supposed to get a token on the login screen, and the token will be shown in an Alert dialog on home screen when the user press a button. But the token is not shown in the Alert dialog. the token is shown after I reload(not refresh the app. I used Live Server extension) the screen three times.
Login.js
const _userLogin = () => {
fetch(URLs._login, {
method: "POST",
headers, body,
})
}).then((response) => response.json())
.then((result) => {
if(result.message !== "Unauthorized / Access Token Expired" && result.message !== "The given data was invalid."){
storeData(result.access_token, result.token_type);
navigation.navigate('HomeScreen');
} else {
Alert.alert("Error", result.message);
}
});
};
const storeData = async (accessToken, tokenType) => {
try {
await AsyncStorage.setItem('#access_token', accessToken);
await AsyncStorage.setItem('#token_type', tokenType);
await AsyncStorage.setItem('#user_auth', tokenType + " " + accessToken);
} catch (e) {
console.log(e);
}
}
Home.js [UPDATE]
const [inputs, setInputs] = React.useState({
userToken: '',
userPointsBalance: '',
expiringOn: '',
});
useEffect (() => {
_dashboard();
})
const getToken = async () => {
inputs.userToken = await AsyncStorage.getItem('#user_auth');
}
const _dashboard = () => {
getToken();
fetch(URLs._dashboard, {
method: "GET",
headers: {
'Authorization': inputs.userToken,
'Content-Type': 'application/json',
},
}).then((response) => response.json())
.then(async (result) => {
storeData(result.code, result.name, result.member_name, result.user_points_balance, result.expiring_on, result.status, result.token_id);
getData();
});
};
const storeData = async (code, name, memberName, userPointsBalance, expiringOn, status, tokenId) => {
try {
await AsyncStorage.setItem('#user_points_balance', userPointsBalance.toString());
await AsyncStorage.setItem('#expiring_on', expiringOn.toString());
} catch (e) {
console.log(e);
}
}
const getData = async () => {
const userPointsBalance = await AsyncStorage.getItem('#user_points_balance');
const expiringOn = await AsyncStorage.getItem('#expiring_on');
setInputs({userPointsBalance: userPointsBalance, expiringOn: expiringOn});
}
return (
<Text>{inputs.expiringOn}<Text>
)
i hope it works
.then(async(result) => {
if(result.message !== "Unauthorized / Access Token Expired" && result.message !== "The given data was invalid."){
await storeData(result.access_token, result.token_type)
.then(res=>
navigation.navigate('HomeScreen')
)
} else {
Alert.alert("Error", result.message);
}
});

Passing query params or body with NextJS + Auth0?

So, my knowledge of next and JS in general is extremely minimal as is my Auth0 knowledge. I was wondering if anyone could suggest how to pass query parameters or a request body to the first block of code below?
I know I can add a body to the fetch function, but when I try to do that in the /pages/profile block below, it seems to break the request.
Even better would be to make this some kind of generic function, where I can pass in a the route, method, and body since all of the routes will be protected anyway.
Any help would be greatly appreciated.
/pages/api/my/user
import { getAccessToken, withApiAuthRequired } from '#auth0/nextjs-auth0';
export default withApiAuthRequired(async function shows(req, res) {
try {
const { accessToken } = await getAccessToken(req, res, {
scopes: ['profile']
});
const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/v1/my/user`, {
headers: {
Authorization: `Bearer ${accessToken}`
},
});
const shows = await response.json();
res.status(200).json(shows);
} catch (error) {
res.status(error.status || 500).json({ error: error.message });
}
});
And here's the snippet that fetches the above:
/pages/profile
const [state, setState] = useState({ isLoading: false, response: undefined, error: undefined });
useEffect(() => {
callApi();
}, []);
const callApi = async () => {
setState(previous => ({ ...previous, isLoading: true }))
try {
const response = await fetch(`/api/my/user`);
const data = await response.json();
setState(previous => ({ ...previous, response: data, error: undefined }))
} catch (error) {
setState(previous => ({ ...previous, response: undefined, error }))
} finally {
setState(previous => ({ ...previous, isLoading: false }))
}
};
const { isLoading, response, error } = state;
Cannot see where your actual problem is - here's a snippet that usually works for me with fetch:
provide headers and body as parameters of an options variable, add the url and you are good to go.
const res = await fetch(url, options)
const protocol = 'https'
const hostname = 'YOURHOSTNAME'
const queryParams = `foo=bar`
const body = []
const url = `${protocol}://${hostname}/api/${endpoint}?${queryParams}`;
const options = {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': `${hostname}`, // set as needed
},
body: body,
method: 'POST',
};
const res = fetch(url, options);
Hope this helps

ReactJS Hook error handeling doesn't catch errors

I am trying to catch a 404 error I receive for some of my API calls.
I am using the matrix API and need to get room names from their id's, which is working. Some of them don't have names which returns a 404 error I am trying to catch. Unfortunately this dosn't work and I don't understand where I'm going wrong. The code itself exectues, but it still throws 404's in the console.
const JoinedRooms = () => {
const [answer, setAnswer] = useState([]);
const [isError, setIsError] = useState(false);
const getAnswer = async () => {
const res = await fetch(`https://example.com/_matrix/client/r0/joined_rooms`, {
headers: {
"Authorization": `Bearer ${localStorage.getItem('mx_access_token')}`
}
});
const answer = await res.json();
const getNames = await Promise.all(answer.joined_rooms.map(async (roomId) => {
setIsError(false);
const res = await fetch(`https://example.com/_matrix/client/r0/rooms/${roomId}/state/m.room.name`, {
headers: {
"Authorization": `Bearer ${localStorage.getItem('mx_access_token')}`
}
});
try {
const roomName = await res.json();
return roomName.name;
} catch (error) {
setIsError(true);
}
}));
setAnswer(getNames);
}
useEffect(() => {
getAnswer();
}, []);
return answer;
}
export default JoinedRooms;
A 404 status code will not throw an error, so your try...catch block won't catch it. Try getting the 404 directly from the res object returned.
const res = await fetch(`https://example.com/_matrix/client/r0/rooms/${roomId}/state/m.room.name`, {
headers: {
"Authorization": `Bearer ${localStorage.getItem('mx_access_token')}`
}
});
if (res.status === 404) {
// handle error
}

Chaining async functions doesn't work correctly

I'm trying to chain two async functions but it seems that the second one is being executed before the first one.
Here is my code
function performAction(e) {
const ZIP = document.getElementById('zip').value;
const fellings = document.getElementById('feelings').value;
console.log(`${baseURL}${ZIP},us&appid=${key}`);
getWeather(baseURL, ZIP, key,).then((data) => {
postData('/addweather', {temperature: data.main.temp ,date:newDate, userResponse: fellings })
}).then(
updateUI()
)}
and This is getWeather()
const getWeather = async(baseURL, ZIP, key) => {
let URL = `${baseURL}${ZIP}&appid=${key}`;
const res = await fetch(URL)
try{
const data = await res.json();
return data;
}catch(error){
console.log("error", error);
}}
and this is postData() which is supposed to execute after the getWeather function is excuted but it isn't.
const postData = async ( url = '', data = {}) => {
console.log(`This is what we fetch ${data.temperature}`);
console.log(`This is what we fetch ${data.date}`);
console.log(`This is what we fetch ${data.userResponse}`);
const response = await fetch(url, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
},
// Body data type must match "Content-Type" header
body: JSON.stringify(data),
});
try {
const newData = await response.json();
console.log(`This is the new Data ${newData.temperature}`);
return newData;
}catch(error){
console.log("error", error);
}}
and this is updateUI()
const updateUI = async () => {
const request = await fetch('/getweather');
try{
const allData = await request.json();
console.log('Get request');
document.getElementById('date').innerHTML = allData.date;
document.getElementById('temp').innerHTML = allData.temperature;
document.getElementById('content').innerHTML = allData.userResponse;
}catch(error){
console.log("error", error);
}}
What happens is that the UI gets updated first so it gets the value of undefined for the first time, and when I reload the page and enter new data the UI get's updated with the data from last time.
You need to return the promise returned from postData:
getWeather(baseURL, ZIP, key,).then((data) => {
return postData('/addweather', {temperature: data.main.temp ,date:newDate, userResponse: fellings })
}).then(() => {
return updateUI()
})
Another way you could write this is like this:
async function run() {
await getWeather(baseURL, ZIP, key)
await postData('/addweather', {temperature: data.main.temp ,date:newDate, userResponse: fellings })
await updateUI()
}
your postData() is also an async function. Therefore you have to await this aswell:
getWeather(baseURL, ZIP, key,).then(async (data) => {
await postData('/addweather', {temperature: data.main.temp ,date:newDate, userResponse: fellings })
}).then(
updateUI()
)}
I didn't have done javascript in a while, but i guess it is more clear in this way:
const performAction = async (e) => {
const ZIP = document.getElementById('zip').value;
const fellings = document.getElementById('feelings').value;
console.log(`${baseURL}${ZIP},us&appid=${key}`);
try{
const data = await getWeather(baseURL, ZIP, key,);
const postData= await postData('/addweather', {temperature: data.main.temp ,date:newDate, userResponse: fellings });
} catch(e) {
console.log(e)
} finally {
updateUI();
}
Also you dont have to await the parsing of the json and the try catch should contain your request:
const postData = async ( url = '', data = {}) => {
console.log(`This is what we fetch ${data.temperature}`);
console.log(`This is what we fetch ${data.date}`);
console.log(`This is what we fetch ${data.userResponse}`);
try {
const response = await fetch(url, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
},
// Body data type must match "Content-Type" header
body: JSON.stringify(data),
});
const newData = response.json();
console.log(`This is the new Data ${newData.temperature}`);
return newData;
}catch(error){
console.log("error", error);
}}

Categories