React Native Network request Failed on fetch - Works Local - ios

I am using some code in a React Native component that is a simple fetch passing a parameter to OMDB API. This could be a CORS issue since if I run it in the format below going directly to omdbapi.com it fails always with Network request Failed. This request however works in the Android emulator on the same network.
// The fetchData function makes an AJAX call to the OMDB API.
fetchData(movieinput) {
console.log("In fetch");
// We pass the movie the user entered in into the URL for the API call.
fetch('http://www.omdbapi.com/?t='+movieinput+'&y=&plot=short&r=json')
.then((response) => response.json())
.then((responseData) => {
// After the data is recieved, we set this.state.movie to the result of the API call.
this.setState({
movie: responseData,
});
})
.done();
}
If however I run the same code going to a local URL that wraps the remote request into a localhost request, it works correctly.
fetchData(movieinput) {
console.log("In fetch");
// We pass the movie the user entered in into the URL for the API call.
fetch('http://localhost:3000/movie/'+movieinput)
.then((response) => response.json())
.then((responseData) => {
// After the data is recieved, we set this.state.movie to the result of the API call.
this.setState({
movie: JSON.parse(responseData),
});
})
.done();
}
Any ideas?

The problem is probably App Transport Security, an iOS specific restriction that (by default) forces apps to use https for all network communication. Here is a video tutorial explaining how to tweak ATS so that your react native app will work: http://codecookbook.co/post/how-to-make-network-requests-in-react-native/

Related

Axios post request network error on android

So i'm posting a formdata object with axios to a node.js server. On iOS everything works perfectly, the data get posted and the image uploaded. But on android i'm getting this error
[AxiosError: Network Error]
here's my axios call
const handleSubmit = async (listing, { resetForm }) => {
const data = new FormData();
listing.images.forEach((image, index) =>
data.append("images", {
name: `product${Math.floor(Math.random() * 1000)}.`,
uri: image,
})
);
const res = await axios
.post("http://192.168.43.8:5000/products/addProduct", data, {
headers: {
"Content-Type": "multipart/form-data",
},
//tried adding this but didn't work out
transformRequest: (data) => data,
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
// handle error
});
}
}
Please note that on iOS it works without a problem.
here's a screenshot of the error when i used the react native debugger
if you use android emulator you need to change your ip to 10.0.2.2
change this:
http://192.168.43.8:5000/products/addProduct
to this:
http://10.0.2.2:5000/products/addProduct
By default http calls are blocked from android 9 version onwards, you either need to make your api calls HTTPS or you need to explicitly allow connection to this IP in your manifest file. Please refer this SO thread. How to allow all Network connection types HTTP and HTTPS in Android (9) Pie?
For me i am getting axios error for my emulator and did not getting any error for ios simulator. The problem with my emulator is that it is not able to connect to Internet.
So I added google DNS server 8.8.8.8 (you can add any DNS server) for my mac and it worked.

How do I get my physical device running React Native on Expo Go to communicate with my app's rails backend api?

I am currently trying to run my react-native/rails app on my phone for testing purposes. I can run my sign in and log in screens fine because they do not communicate with my server until the user info is entered. When running my server i use:
$ rails s --binding=0.0.0.0
I do not receive any errors other than knowing my server is not being communicated with. This all works fine on my Android Studio Emulator as well.
// one of my fetch GET requests
export function requestCurrentUser(username, auth_token) {
return function action(dispatch) {
const request = fetch(`'http://10.0.2.2:3000'/users/${username}`, {
method: 'GET',
headers: {
"Authorization": auth_token
}
});
return request.then(
response => response.json(),
err => console.log("user error"),
)
.then(
json => dispatch(receiveCurrentUser({id: json.id, email: json.email, username: json.username})),
err => console.log("user json error"),
);
}
}
I've tried changing my Phone IP settings to a 10.0.2.2 Gateway, and using my phone's IP in my fetch request. I feel like I am missing something conceptually. Thanks in advance.
In fetch request you need to use the IP from the machine that are running the rails server,
probably your notebook and use the same network to connect your app and your rails backend api. In order to test, you can try directly access your api in your phone browser accessing http://IP_FROM_RAILS_MACHINE:3000

How to use Websocket (socket.io) with Ruby?

I need to implement WebSocket synchronization in our Rail project. MetaApi project's use Socket.Io as default support. Only found 2 projects (websocket-client-simple) and outdated with native socket.io. We try to implement this with Faye-Websocket and socketcluster-client-ruby but without success.
Code Example
import ioClient from 'socket.io-client';
const socket = ioClient('https://mt-client-api-v1.agiliumtrade.agiliumtrade.ai', {
path: '/ws',
reconnection: false,
query: {
'auth-token': 'token'
}
});
const request = {
accountId: '865d3a4d-3803-486d-bdf3-a85679d9fad2',
type: 'subscribe',
requestId: '57bfbc9f-108d-4131-a300-5f7d9e69c11b'
};
socket.on('connect', () => {
socket.emit('request', request);
});
socket.on('synchronization', data => {
console.log(data);
if (data.type === 'authenticated') {
console.log('authenticated event received, you can send synchronize now');
}
});
socket.on('processingError', err => {
console.error(err);
});
Socket.io protocol is a bit more complicated than a simple websocket connection, with the latter being only one of the used transports, see description in official repository. Websockets are used only after initial http handshake, so you need a somewhat full client.
I'd start with trying to consume events with a js client stub from browser, just to be sure the api is working as you expect and determine used and compatible socket.io versions (current is v4, stale ruby clients are mostly for v1). And you can peek into protocol in browser developer tools.
Once you have a successful session example and have read protocol spec above - it will be easier to craft a minimal client.

Accessing network responses in Cypress.io

I'm working on testing an OpenID Connect service, using Code and Implicit Flow. I would really like to be able to access the messages I get back from the service, especially the 303 See Other message which has the ID Token.
If someone can advise on how to get to response messages I would really appreciate it. Since the services exposes a HTML login page what happens is a
cy.get("#loginButton").click()
so I don't send a cy.request() and that is because I want to test login using the front-end.
You should leverage cy.route, how it works:
before cy.visit you need to add cy.server(), it allows Cypress to intercept every request
you add an alias to the login request
cy.route({
method: "POST",
url: '/auth/token' // this is just an example, replace it with a part of the real URL called to log in the user
}).as("route_login"); // that's the alias, we'll use in soon
right after the cy.get("#loginButton").click() command, you can wait for the login request to happen
cy.wait("#route_login").then(xhr => {
// you can read the full response from `xhr.response.body`
cy.log(JSON.stringify(xhr.response.body));
});
your final test should be something like
it("Test description", () => {
cy.server();
cy.visit("YOUR_PAGE_URL");
cy.route({
method: "POST",
url: '/auth/token'
}).as("route_login");
cy.get("#loginButton").click();
cy.wait("#route_login").then(xhr => {
// you can read the full response from `xhr.response.body`
cy.log(JSON.stringify(xhr.response.body));
});
});
Let me know if you need more help 😉
cy.server() and cy.route() are deprecated in Cypress 6.x
Use cy.intercept() instead:
cy.intercept('POST', '/organization', (req) => {
expect(req.body).to.include('Acme Company')
})
Your tests can intercept, modify and wait on any type of HTTP request originating from your app.
Docs: https://docs.cypress.io/api/commands/intercept.html (with examples)

React native PouchDB get hangs

I have a promise chain where I get the content from local DB, update it with the latest fetched from API. This cycle is run whenever user eg opens a content. It works well. Except when the user is opening the app through a deep link. Eg, I go to the company website, I have the deep link option in the safari, I open it. It successfully fetches the content opened from the website, goes into the promise lifecycle where it tries to load and update the content but it just hangs. All input data is correct and it doesn't make sense why it hangs at all.
PouchDB is using adapter pouchdb-adapter-react-native-sqlite with react-native-sqlite-2
createDBIndex()
.then(() => {
console.groupCollapsed('Updating existing content');
console.log(toUpdateArray);
console.log('Fetching articles and indexes');
return Promise.all(toUpdateArray.map(({ _id }) => DB.articles.get(_id)));
})
.then(dbArticles => {
console.log('Resolving finders-keepers');
console.log(dbArticles);
const updatedContent = dbArticles.map(dbItem => {
const toUpdate = toUpdateArray.find(item => item._id === dbItem._id);
return {
...dbItem,
...toUpdate,
expire: moment().add(1, 'd').format()
};
});
return DB.articles.bulkDocs(updatedContent).then(() => updatedContent);
})
.then(updatedDBArray => {
console.log('update result', updatedDBArray);
console.groupEnd();
return updatedDBArray;
})
The last console.log it gives is Fetching articles and indexes and the whole app freeze. tried to print the PouchDB get function result or error but nothing. It doesn't get resolved or rejected.
What I can share is that recently people have problems using PouchDB in a React Native environment which is using AsynchStorage as its backing storage. Take a look at this question and that question and also this issue.

Resources