i am new at react native. I fetch data on Firebase but i want to fetch it JSON file. My JSON file like this: enter image description here
how can i change firebase url to my php json url?
PLEASE HELP ME
This is my code:
return async (dispatch, getState) => {
// any async code you want!
// const userId = getState().auth.userId;
try {
const response = await fetch(
'https://shopapp-f9964.firebaseio.com/products.json'
);
if (!response.ok) {
throw new Error('Something went wrong!');
}
const resData = await response.json();
const loadedProducts = [];
for (const key in resData) {
console.log(resData[key].description);
loadedProducts.push(
new Product(
0,
0,
resData[key].product_image,
resData[key].description,
resData[key].price,
)
);
}
dispatch({
type: SET_PRODUCTS,
products: loadedProducts,
//userProducts: loadedProducts.filter(prod => prod.ownerId === userId)
});
} catch (err) {
// send to custom analytics server
throw err;
}
};
Here is the way to get from API (or Json response).
fetch('https://mywebsite.com/endpoint/', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
}),
});
Here is the official docs, it really helps for you to understand data from JSON file
https://reactnative.dev/docs/network
here is the working example on Snack
https://snack.expo.io/#asad_4561/b21f6d?session_id=snack-session-EGg1r5WPo&preview=true&platform=web&iframeId=g11cgnoglm&supportedPlatforms=ios,android,web&name=Fetch%20Example&description=Example%20usage&waitForData=true
Here is some good refs for your problem, by reading them your problems will be solved:
Medium: This is very good
RN docs
Another Good ref
Related
have a good time! I use axios to send a post request to the api http://freerealapi.com/ I work based on the document but it gives me an error 400 What should I do?
const buildDiscount = async token => {
let data = new FormData();
data.append('title', keyCodes);
data.append('text', 'test text');
data.append('image', file);
data.append('tags', 'one,two,three');
try {
const res = await axios.post('https://api.freerealapi.com/panel/blogs/', data, {
headers: {
'Content-Type': 'multipart/form-data',
Authorization: `Bearer ${token}`,
},
})
console.log(res.data);
} catch (error) {
console.log(error.response);
}
}
This function is most probably missing those 2 extra variables ( keyCodes, file ), can you provide those inputs to the function? That's probably the reason why the request is being malformed.
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.
I am getting "MissingServletRequestPartException: Required request part 'studentImg' is not present", It works fine with Postman but not with React. I am trying to call a end point in a Spring boot restful API.
Backend Controller Code:
#PostMapping("/add")
public ResponseEntity<StudentFile> addStudentImg(HttpServletRequest request, #RequestParam("studentImg") MultipartFile studentImg) {
boolean isStudent = (Boolean) request.getAttribute("isStudent");
if(false == isStudent) {
throw new EtAuthException("Only Student can add their image.");
} else {
Long addedBy = (Long) request.getAttribute("studentId");
StudentFile studentFile = studentFileService.addStudentImg(studentImg, addedBy);
return new ResponseEntity<>(studentFile, HttpStatus.CREATED);
}
}
React Components' Code Snippets:
handleStudentImgChange(event) {
this.setState({ studentImg: event.target.files[0] });
}
handleOnSubmit(event) {
event.preventDefault();
const { studentImg } = this.state;
this.props.addStudentImg(studentImg);
this.setState({ studentImg: null });
}
const mapDispatchToProps = (dispatch) => {
return {
addStudentImg: (studentImg) => {
dispatch(addStudentImgAction(studentImg));
},
};
export default connect(null, mapDispatchToProps)(AddStudentImgPage);
React Axios Call:
import axios from "axios";
const token = "...";
export const addStudentImg = (studentImg) => {
let bodyFormData = new FormData();
bodyFormData.append("studentImg", studentImg[0]);
const headers = {
Authorization: `Bearer ${token}`,
// Accept: "application/json",
"Content-Type": "multipart/form-data",
};
return axios
.request({
method: "POST",
url: "http://localhost:8080/api/studentfiles/add/",
data: bodyFormData,
headers: headers,
})
.then((res) => res.data);
};
The network log: enter image description here enter image description here
I'm unable to find any solution regarding that. Please give suggestions.
Thanks in Advance :D
You already set files[0] when you set
handleStudentImgChange(event) {
this.setState({ studentImg: event.target.files[0] });
}
then again, you are trying to access
bodyFormData.append("studentImg", studentImg[0]);
This, seems wrong, change this to
bodyFormData.append("studentImg", studentImg);
and see if it works..
First I changed these lines:
let bodyFormData = new FormData();
bodyFormData.append("studentImg", studentImg[0]);
With these:
const bodyFormData = new FormData();
const blob = new Blob([studentImg], {type: studentImg.type});
bodyFormData.append("studentImg", blob);
When I logged studentImg just above the bodyFormData, I get the response something like: {type: 'ADD_STUDENT_IMG', studentImg: File} where it was json object like this:
Then, I put thse lines and these are just working fine with it.
const bodyFormData = new FormData();
const blob = new Blob([studentImg.studentImg], {
type: studentImg.studentImg.type,
});
bodyFormData.append("studentImg", blob);
To understand how these lines are working:
Please read the FormData docs and also some additional information about how it's serialized over here.
If any queries, please ask. (P.S. prescriptionImg == studentImg for fig.)
Thanks :D
So I moved over a non-reusable fetch request code snippet to my API:
let response = await fetch(visitURL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + userJWT
},
body: JSON.stringify(endingVisit)
});
if (response.ok) {
let {visitId, createdAt} = await response.json();
const viewVisitDto = new ViewVisitDto(`${visitId}${createdAt}${visitorId}${doctorId}${oldPatientId}`);
return viewVisitDto;
} else {
throw new Error("deactivated!")
}
I was able to get this far:
axios.post(visitURL, {
headers,
body: JSON.stringify(visit)
}).then((response) => {
console.log(response);
}).catch((error) => {
console.log(error);
})
But does not exactly give me the visitId and createdAt from the response and I cannot use a response.ok nor a response.json(). Essentially I need to pull out that visitId and createdAt that should be coming back in the response.
I also tried just using node-fetch library, but although in VS code it seems to accept it, TypeScript is not happy with it even when I do install #types/node-fetch and even when I create a type definition file for it, my API just doesn't like it.
Guessing what you are after is
// don't know axios, but if it returns a promise await it
const dto = await axios.post(visitURL, {
headers,
body: JSON.stringify(visit)
}).then((response) => {
// parse response
return {resonse.visitId, resonse.createdAt}
}).then(({visitId, createdAt}) => {
// form dto (where are other vals)?
return new ViewVisitDto(`${visitId}${createdAt}${visitorId}${doctorId}${oldPatientId}`);
}).catch((error) => {
console.log(error);
})
However - you don't mention where doctorId and oldPatientId come from... You try providing more info, including output of the console.log's and the surrounding code
I seem to be having an issue with getting the expected response from a fetch call within a firebase cloud function. I'm sure it's due to my lack of knowledge on how the responses, promises, etc. work.
I'm trying to use atlassian crowd's rest api for SSO. If I use postman, I can get the desired results from the request. So I know that part of it is working.
What led me to using a cloud function is that making the same request using fetch was resulting in CORS issues from localhost. I figured if I can take the browser out of the equation, then the CORS issues would disappear. Which they have, but I'm not getting the desired response.
My cloud function looks like this:
const functions = require('firebase-functions');
const fetch = require('node-fetch');
const btoa = require('btoa');
const cors = require('cors')({origin:true});
const app_name = "app_name";
const app_pass = "app_password";
exports.crowdAuthentication = functions.https.onRequest((request, response)=>
{
cors(request, response, () =>{
let _uri = "https://my.server.uri/crowd/rest/usermanagement/1/session";
let _headers = {
'Content-Type':'application/json',
'Authorization':`Basic ${btoa(`${app_name}:${app_pass}`)}`
}
let _body = {
username: request.body.username,
password: request.body.password
}
const result = fetch(_uri, {
method: 'POST',
headers: _headers,
body: JSON.stringify(_body),
credentials: 'include'
})
response.send(result);
})
})
I'm then making the call in my application using fetch to the firebase endpoint and passing the username/password:
fetch('https://my.firebase.endpoint/functionName',{
method: 'POST',
body: JSON.stringify({username:"myusername",password:"mypassword"}),
headers: {
'Content-Type':'application/json'
}
})
// get the json from the readable stream
.then((res)=>{return res.json();})
// log the response - {size:0, timeout:0}
.then((res)=>
{
console.log('response: ',res)
})
.catch(err=>
{
console.log('error: ',err)
})
Thanks for looking.
Edit of May 2020
Note that request-promise is deprecated and I recommend to use axios.
Update following our discussion in the comments below
It appears that it doesn't work with the node-fetch library and that you should use another library like request-promise.
Therefore you should adapt your code as follows:
//......
var rp = require('request-promise');
exports.crowdAuthentication = functions.https.onRequest((request, response) => {
cors(request, response, () => {
let _uri = "https://my.server.uri/crowd/rest/usermanagement/1/session";
let _headers = {
'Content-Type': 'application/json',
'Authorization': `Basic ${btoa(`${app_name}:${app_pass}`)}`
}
let _body = {
username: request.body.username,
password: request.body.password
}
var options = {
method: 'POST',
uri: _uri,
body: _body,
headers: _headers,
json: true
};
rp(options)
.then(parsedBody => {
response.send(parsedBody);
})
.catch(err => {
response.status(500).send(err)
//.... Please refer to the following official video: https://www.youtube.com/watch?v=7IkUgCLr5oA&t=1s&list=PLl-K7zZEsYLkPZHe41m4jfAxUi0JjLgSM&index=3
});
});
});
Initial answer with node-fetch
The fetch() method is asynchronous and returns a Promise. You therefore need to wait this Promise resolves before sending back the response, as follows:
exports.crowdAuthentication = functions.https.onRequest((request, response)=>
{
cors(request, response, () =>{
let _uri = "https://my.server.uri/crowd/rest/usermanagement/1/session";
let _headers = {
'Content-Type':'application/json',
'Authorization':`Basic ${btoa(`${app_name}:${app_pass}`)}`
}
let _body = {
username: request.body.username,
password: request.body.password
}
fetch(_uri, {
method: 'POST',
headers: _headers,
body: JSON.stringify(_body),
credentials: 'include'
})
.then(res => {
res.json()
})
.then(json => {
response.send(json);
}
.catch(error => {
//.... Please refer to the following official video: https://www.youtube.com/watch?v=7IkUgCLr5oA&t=1s&list=PLl-K7zZEsYLkPZHe41m4jfAxUi0JjLgSM&index=3
});
})
})
In addition, note that you need to be on the "Flame" or "Blaze" pricing plan.
As a matter of fact, the free "Spark" plan "allows outbound network requests only to Google-owned services". See https://firebase.google.com/pricing/ (hover your mouse on the question mark situated after the "Cloud Functions" title)