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
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
}
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);
}
});
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
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
}
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);
}}