React native version 63 image uploading issue - ios

Missing request token for request: <NSURLRequest: 0x282528c80> { URL: file:///var/mobile/Containers/Data/Application/0EFA47FC-4E6B-45B2-98CF-8F43676E6AB4/Documents/signature.png }
Screenshot attached

Replace "file://" to "/private"
dataForm.append('file', { uri: Platform.OS=='ios'?photo.uri.replace("file://", "/private"):photo.uri, name: 'photo.jpg', type: 'image/jpg' });
IOS : photo.uri.replace("file://", "/private")
It only works for the real device, on simulator still give the error but at least you can deploy your app until this issue is patched

Related

IOS iPhone browsers does not accept video files via upload dialog

We are using IOS file upload dialog in order to use video files with our service using react.
All video files are working in android platforms and all browsers in linux and MacOS. However, when we use video files with upload dialog in IOS IPhones such as Iphone 14 Pro Max, then the compress process starts and following that the dialog rejects the video file.
We have been debugging with browserstack using a real phone in a simulator, however no luck until this point.
When we select the file, it firstly runs a compression activity then changes the name of the file to an intermediate file name (as below, the original file name is different), and then upload procedure fails.
Below is the react part which triggers upload mechanism which works with every platform and operating system with exception of IOS.
export const UploadVideo = async (file, signedurl, uploading) =>
{
let resultState = { state: '', data: {} };
if (SERVER_STATUS !== 'localhost')
{
await axios({
method: 'put',
url: signedurl,
data: file,
headers: { 'Content-Type': 'application/octet-stream', },
onUploadProgress: uploading
}).then(function (response)
{
resultState.state = 'success';
}).catch(function (error)
{
resultState.state = 'error';
resultState.data.message = error.message;
window.toastr.error(error.message);
})
} else resultState.state = 'success';
return resultState;
}
The error message I notice here, OS Status error -9806 refers to, according to osstatus.com a secure transport result code. More specifically this one, on Apple's documentation
My take here is that the system is not trusting this URL, I would suggest adding your URL to trusted domains under NSAppTransportSecurity in the Info.plist file. More info on how to do that here.
This is not a solution I would go for for a production app tho, you might want to have a valid certificate for your production URL and app.
Hope this helps.

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.

Video is uploaded as an image from iOS device, how to upload properly

I have an app that gets the images/videos from the mobile gallery, then uploads one of them to a server,
here are the steps i take, which works fine on Android:
1-get data from mobile storage:
MediaLibrary.getAssetsAsync({
first: 20,
mediaType: [MediaLibrary.MediaType.video, MediaLibrary.MediaType.photo]
})
2-upload to server:
formData.append('images[]', {
uri: localUri,
name: isVideo ? 'untitled.mp4' : 'untitled',//for testing
type: isVideo ? 'video/mp4' : 'image/jpeg'
})
axios.post(`url`, formData, {headers: headers,timeout:999999})
The problem is videos are uploaded as an image (only the first frame of the video), while it gets uploaded successfully on Android, the problem is only present on iOS.
The uri of the retrieved files is as follows:
assets-library://asset/asset.MP4?id=xxx&ext=MP4
Quick notes:
1 - the video is played fine locally using the <Video> component from Expo
2 - i tried using the CameraRoll API, but it gives the same results, and is a little buggy
any help would be appreciated
You can update to expo SDK 36 and you will be able to solve this problem by using localUri returned by MediaLibrary.getAssetInfoAsync
ex.
// get asset id like B84E8479-475C-4727-A4A4-B77AA9980897/L0/001
const info = await MediaLibrary.getAssetInfoAsync(asset.id)
const uri = info.localUri // use this for upload
Reffer this comment on github.
https://github.com/expo/expo/issues/3177#issuecomment-510096711

rn-fetch-blob on real iPhone failing to upload image (localhost testing)

I'm using react-native-image-picker (^0.28.0) along with rn-fetch-blob (^0.10.15).
It works so far when using a Simulator, but when I use it on real iPhone, the image isn't uploading, it fails to upload with the following error that is being catched by the promise.
"Error: Could not connect to the server."
(Yes, server is up and running)
If you see this, you might think it's a backend issue but other requests work fine on real device, this one is the only having problems. The image request being sent is this one:
{
data: "RNFetchBlob-file:///var/mobile/Containers/Data/Application/843A96A1-0000-40D3-B50F-95D69B94B87A/tmp/5D22283B-2014-4E9E-AC3E-AE677D91A366.jpg"
filename: "IMG_6834.jpg"
name: "pictures"
type: "image/jpeg"
}
The only difference with the simulator device and my iPhone is the data path. Where on simulator is like "RNFetchBlob-file:///Users/marian-mac/Library/Developer/CoreSimulator/Devices/....etc"
Any idea why should be different from the simulator on this? It seems to be sending the same request.
Some extra info, when I preview the image in an Image component, it shows well too. So it seems the path is correct on the real iPhone.
This is the method to upload image
uploadPicture: function(data, token) {
return RNFetchBlob.fetch('POST', Constants.baseUrl + '/picture', {
Authorization: "Bearer " + token,
'Content-Type': 'multipart/form-data;boundary=***BOUNDARY***'
}, data);
},
And this is how I build the picture request array, this.state.images contains the image-picker data.
this.state.images.forEach((image) => {
reqData.push({
data: image.imageFile,
filename: image.fileName.split('.')[0] + '.jpg',
name: 'pictures',
type: image.type
})
});
The problem could be that you are uploading to a non-https url. Had this same issue and the nsAllowArbitraryLoads made it work on simulator and gave error when using it on a real device.
Had to wait until it became https
It does not seem to be the problem with http or https. (mine is http)
I'm having a file on this path:
filepath =/var/mobile/Containers/Data/Application/F8F06A2A-C04D-4B6D-A316-F879E144366B/Documents/test.wav
I tried RNFetchBlob.wrap(filePath) but no use.
So I tried to add this file to the asset of ios project and using RNFetchBlob.wrap(RNFetchBlob.fs.asset('test.wav')). Voila, it works.
As a result, it seems to be the problem with filepath

multipart/form-data not working on ionic iOS

I have an ionic 3 project that allows for file upload to the server. The following code is working fine from Android. But on iOS it appears to get blocked (i.e. the server code at /upload.php is obviously the same in both cases, but coming from iOS it does not receive any of the posted data).
this.http.setDataSerializer('urlencoded');
this.http.post("http://example.com/upload.php", {
name: this.filename,
data: this.datafile
}, {"Content-Type":"multipart/form-data"})
.then(res => {
console.log('success response: ' + res.data);
}, error => {
console.log(error: ' + error);
});
Any ideas?
Is there some setting in xCode that needs to be configured to allow multipart/form-data posts to work? Or perhaps somewhere to white list the domain to allow it?
Turned out to be on the server side. Apparently PHP receives the post differently from Android as it does iOS. $_REQUEST["xxxx"] works fine for Android but in order to work for both it required this:
$postdata = file_get_contents("php://input");
parse_str($postdata, $param);
// then available as $param["xxxx"]
Thought I'd update the answer here in case anyone else bumps into this. Awfully obscure and took me days to figure out!

Resources