I have this fetch() method that is sending data from my react-native app to a laravel method
async handleSubmit(){
var me = this.state.message;
console.log('this connected',me);
try {
let response = await fetch('http://no-tld.example/androidLogin', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: 'chesterfield#gmail.com',
password: '123456',
})
});
//let res = await response.text();
if (response.status >= 200 && response.status < 300) {
console.log(response);
} else {
//Handle error
// let error = res;
// throw error;
}
} catch(error) {
//console.log(res);
}
}
I can receive the data using this method
public function androidLogin(){
$rawData = file_get_contents("php://input");
$postedValue = json_decode($rawData);
//parse_str($postedValue, $output);
return response()->json([
'name' => $postedValue,
'route' => $postedValue
]);
}
and attempting to return the just posted data. The posted data looks like this
12:35:07 PM:
{"type":"default","status":200,"ok":true,"headers":{"map":{"connection":["Keep-Alive"],"content-length":["54"],"content-type":["application/json"],"set-cookie":["XSRF-TOKEN=eyJpdiI6IlF1NWlLOE9rVCtlUXNpYzBFSTV0c0E9PSIsInZhbHVlIjoiNWtGenprRmJOYTVsc2dQRjNrcmpxZXhWeFZRd1NZSzdiOWFKUUZTZmJJaEN6U0RnbW9uOVZ4bGUrV2ZMYUlIb0NQNHFrT1pCWXB0dnlwTjhPWm56ZWc9PSIsIm1hYyI6IjU3NDJkNWE5M2U4YmIwNTUwNzhkZTM4ZTRlNDc5OTZhNjczYWEyODU0OGNmN2ViNDdkYTM4YjdjY2U1ZWE1ZmYifQ%3D%3D;
expires=Fri, 09-Jun-2017 11:35:07 GMT; Max-Age=7200; path=/,
laravel_session=zqcMrXeuwwGpEsR8Jh2WakDg0cdqLod4QsfMnfcd; expires=Fri,
09-Jun-2017 11:35:07 GMT; Max-Age=7200; path=/;
HttpOnly"],"access-control-allow-methods":["GET, POST, PUT, DELETE,
OPTIONS"],"access-control-allow-origin":["*"],"cache-control":["no-cache,
private"],"server":["Apache/2.4.18
(Ubuntu)"],"keep-alive":["timeout=5, max=100"],"date":["Fri, 09 Jun
2017 09:35:07
GMT"]}},"url":"http://no-tld/androidLogin","_bodyInit":"{\"email\":\"chesterfield#gmail.com\",\"password\":\"123456\"}","_bodyText":"{\"email\":\"chesterfield#gmail.com\",\"password\":\"123456\"}"}
I now want to access the returned email from my native-react app.
console.log(response.email); returns null. How can i access the returned email value in react native?
Try below fetch call,
React-native log-android //Android
or react-native log-ios // IOS
use to see response data or error details
fetch('http://no-tld.example/androidLogin', {
method: 'POST',
headers: { 'Accept': 'application/json','Content-Type': 'application/json',},
body: JSON.stringify({ email: 'chesterfield#gmail.com', password: '123456'})
}).then((response) => response.json())
.then((responseData) => {
console.log("responseData : " +responseData); // fetch response data
}).catch((error) => {
console.log("error : " +error); // error
});
I fixed it this way
async handleSubmit(){
var me = this.state.message;
console.log('this connected',me);
try {
let response = await fetch('http://198.74.51.225/androidLogin', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: 'chesterfield#gmail.com',
password: '123456',
})
});
let res = await response.text();
if (response.status >= 200 && response.status < 300) {
let userData = JSON.parse(res);
console.log(userData.email);
} else {
//Handle error
// let error = res;
// throw error;
}
} catch(error) {
//console.log(res);
}
}
Just to be sure of the post data returned, you can modify the posted data in the server side and return it using this function
//Android Login
public function androidLogin(){
$rawData = file_get_contents("php://input");
$postedValue = json_decode($rawData,true);
$token = rand(400,7833);
return response()->json([
'email' => $token."_".$postedValue['email'],
'password' => $postedValue['password']
]);
}
For this to work, i had to also allow cors using this middleware
<?php
namespace App\Http\Middleware;
use Closure;
class Cors {
public function handle($request, Closure $next)
{
return $next($request)
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
}
}
and i used it in my route like this
//Android
Route::group(['middleware' => ['cors']], function() {
Route::post('androidLogin', 'Auth\LoginController#androidLogin');
});
Hope that helps someone trying to post or get from a react-native app.
Related
signIn = () => {
//post data to express backend
fetch('http://10.0.2.2:3000/api/v1/auth', {
method: 'POST',
header: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: `login=${this.state.login}&password=${this.state.password}`
})
.then((response) => response.json())
.then ((res => {
if(res.status === 200) {
AsyncStorage.setItem('user', this.state.login);
this.props.navigation.navigate('Authorized')
} else {
alert("Response:", res);
}
}))
.done();
}
The above is for React-Native. And below is the express backend:
router.post('/', function(req,res){
var login= req.body.login;
var password = req.body.password;
var sql = `SELECT * FROM users WHERE username = '${login}' OR number = '${login}' AND password = ${password}`
db.query(sql, function (err, rows, fields) {
if (err) {
res.status(500).send({error: 'Something went wrong!'})
} else {
if(rows.length > 0) {
if (rows[0].password == password) {
res.status(200).send({success: 'Login Successful'})
}
} else {
res.status(404).send({error: 'Email or Password does not match!'})
}
}
})
});
I think there is nothing getting into a response or maybe some other problem which I am unable to figure out the moment.
I want to upload photos with React Native. My API attempt from Postman resulted in a positive.
But React Native didn't make it.
React Native function
uploadPhoto = async response => {
const data = new FormData();
data.append("image", {
uri: response.uri,
type: response.type,
name: response.fileName,
length:response.fileSize
});
const config={
headers:{
'Content-type':'multipart/form-data'
}
}
axios
.post('https://localhost:44337/api/values',JSON.stringify(data),config)
.then(response=>{
console.log(response);
})
.catch(error=>{console.log(error);})
};
Asp.net Core side
[HttpPost]
public IActionResult Post([FromForm]PhotoModel bookData)
{
//installation codes
return Ok();
}
Model
public class PhotoModel
{
public IFormFile image { get; set; }
}
Result:Network Error
You can try in react native code.
Hope helpful for you.
export const uploadImages = async (formData) => {
try {
let response = await axios({
url: urlUploadImages,
method: 'POST',
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, GET, PUT, OPTIONS, DELETE',
'Access-Control-Allow-Headers': 'Access-Control-Allow-Methods, Access-Control-Allow-Origin, Origin, Accept, Content-Type',
'Accept': 'application/x-www-form-urlencoded',
'Content-Type': 'multipart/form-data',
'Authorization': 'Bearer ' + global.TOKEN || 'Bearer ' + await AsyncStorage.getItem("#loggedInUserID:token"),
},
data: formData,
});
console.log('uploadImages API response', response)
if (response.status === 401) {
return global.UNAUTHORIZE;
} else {
// let json = await response;
if (response.status === 200) {
return response.data;
} else {
return global.FAIL;
}
}
} catch (error) {
console.log('Upload Failed', error);
}
};
You don't have to change from form data back to JsonString. Send it right away.
.post('https://localhost:44337/api/values',data,config)
Remove json.stringify and verify that you set right values:
const form = new FormData();
form.append('image', {
uri: "file:///...",
type: 'image/jpg',
name: 'image.jpg',
});
first of all i am working with react-native
i wanted to use Custom Claims on my project since it seems to fit the role distribution i expect to use on my app.
after setting my app following the documentation i succeed on creating some functions
but, here's the thing, when i try to call a function by fetching the endpoint i always get this error :
in the console
error
:
Object
message
:
"Bad Request"
status
:
"INVALID_ARGUMENT"
in firebase console
addAdminRoleTest Request body is missing data. { email: 'dev#test.com' }
i couldn't find any answer to that except that i send wrong information from my fetch but i don't understand why.
i even tried to simplify my function only to get the data i sent but i had the exact same error
find below my cloud function & the calling method :
functions/index.js
exports.addAdminRole = functions.https.onCall((data, context) => {
// get user
return admin.auth().getUserByEmail(data.email).then(user => {
// if not already (admin)
if(user.customClaims && (user.customClaims).admin === true) {
return;
}
// add custom claim (admin)
return admin.auth().setCustomUserClaims(user.uid, {
admin: true
});
}).then(() => {
return {
message: `Bravo : ${data.email} fait partie de l'équipe Admins`
}
}).catch(err => {
return err;
});
});
simplified function :
exports.addAdminRoleTest = functions.https.onCall(data => {
console.log("parse data : "+JSON.parse(data));
return (
JSON.parse(data)
);
});
adminScreen.js
function httpAddAdminRole() {
const initRequest = {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
body:JSON.stringify({
email: 'dev#test.com'
})
}
console.log(initRequest);
return fetch('https://us-central1-my-project.cloudfunctions.net/addAdminRole', initRequest)
.catch(err => console.log(err))
.then(res => res.json())
.then(parsedRes => {
console.log(parsedRes);
});
}
in the end this was mostly json knowledge that missed me
my body should have data included
here's the answer i came to :
functions/index.js
exports.addAdminRole = functions.https.onCall((data, context) => {
const dataParsed = JSON.parse(data);
// get user
return admin.auth().getUserByEmail(dataParsed.email).then(user => {
// if not already (admin)
if(user.customClaims && (user.customClaims).admin === true) {
console.log(dataParsed.email + " is already an Admin");
return;
}
// add custom claim (admin)
return admin.auth().setCustomUserClaims(user.uid, {
admin: true
});
}).then(() => {
return {
message: `Bravo : ${dataParsed.email} is now an Admin`
}
}).catch(err => {
return err;
});
});
adminScreen.js
function httpAddAdminRole(mail) {
const initRequest = {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
body:JSON.stringify({
data:JSON.stringify({
email: mail
})
})
}
console.log(initRequest);
return fetch('https://us-central1-my-project.cloudfunctions.net/addAdminRole', initRequest)
.catch(err => console.log(err))
.then(res => res.json())
.then(parsedRes => {
console.log(parsedRes);
});
}
I have a doFetch function that handles all my api calls:
const doFetch = function(params){
...
// Make request using Axios. Axios is promise based.
return axios({
method: method,
url: baseUrl + url,
data: queryParams,
timeout: timeout,
headers: {
'Content-Type': contentType,
'Authorization': `bearer ${Auth.getToken()}` // set the authorization HTTP header
},
responseType: responseType
}).then((response) => {
if(typeof params.callback === "function"){
params.callback(response);
}
else {
return response;
}
}).catch((err) => {
if(typeof params.error === "function") {
if (err.response) {
params.error(err.response.data);
}
}
else{
if (err.response) {
return err.response.data;
}
else{
return err;
}
}
});
};
One such api call is returning a custom error like so (express server):
return res.status(400).json("There was an error on the server.");
The function that calls doFetch is saveUser:
saveUser(userObj).then((response) => {
console.log("No Error");
}).catch((error) => {
console.log("Error:", error);
});
The problem is that I am seeing No Error in the terminal, when I should only be expecting the error message to show. Any ideas?
I like to return promise exactly, to be sure that it does/returns what I want.
I don't like to rely on "promise"-s of 3rd parties.
So I would recommend You to wrap it inside of promise and resolve/reject responses/errors manually:
const doFetch = params => {
...
// Make request using Axios. Axios is promise based.
return new Promise((resolve, reject) => {
axios({
method: method,
url: baseUrl + url,
data: queryParams,
timeout: timeout,
headers: {
'Content-Type': contentType,
'Authorization': `Bearer ${Auth.getToken()}` // set the authorization HTTP header
},
responseType: responseType
})
.then((response) => {
console.info('doFetch:', response); // for debug purposes
if(typeof params.callback === "function"){
params.callback(response);
}
resolve(response);
})
.catch((err) => {
console.error('doFetch:', err); // for debug purposes
const error = (err.response) ? err.response.data : err;
if(typeof params.error === "function") {
params.error(error);
}
reject(error);
});
};
};
I came around this solution but this is not working for me.
Following is my code:
axios.post('http://myurl/api/login', {
email: 'john#doe.com',
password: '123456'
}, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
}).then(response => {
if (response.data) {
this.AuthToken = response.data.token
console.log(this.AuthToken)
axios.get('http://myurl/userdetails/:uid', {
uid: 'D123'
}, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': this.AuthToken
}
}).then(response => {
if (response.data) {
// this.AuthToken = response.data
console.log(response.data)
}
}).catch(error => {
console.log('User Data response Error: ' + error)
})
}
}).catch(error => {
console.log('Login Error: ' + error)
})
I'm getting token from the first POST Login API call. I used that toke to pass into another API call as Authentication token. But I get error: Missing Authorization Headers
Found the solution:
axios.defaults.headers.common['Authorization'] = this.AuthToken;
Try to add another header. "Access-Control-Allow-Headers" : "*".