We have a capacitor app that allows the user to upload a profile picture. The problem is that if the image is too large, uploading fails. I’ve read the paragraph in the Http API documentation about large files: The solution helps for android, but not for iOS.
My question: what’s the best way to upload a user selected image from the app?
In my testing so far, anything above 1.5MB fails (roughly, not consistent)?
We can use the camera API and set maximum width and height and quality, which is great! Although this does not guarantee a specific file size.
How can we get the best maximum quality image upload without going over the limits?
Context:
After selecting an image, we allow the user to further crop the image. We currently do this frontend, which fails also sometimes because of memory constraints. And we can move this to the backend, but the point is: we want the original file upload to be as high quality as possible, so that the crop is also still of good quality.
Native support timeline?
the Http API mentions file upload support coming at some point. Does anyone know estimated timeline for this?
Cordova plugin?
Also I found a cordova plugin that seems to allow large files. I don’t think we can just use this plugin in a Capacitor project can we?
(This is our first project with Capacitor and we’ve never used ionic/cordova yet)
in capacitor project it’s okay to mix capacitor plugins with cordova plugins, “If you can find a Capacitor plugin that does what you want, prioritize that”.
When using pluigns capacitor/cordova it’s good to check when last commit was done, and it seems like cordova-plugin-file-transfer not actively maintained. Sometimes plugins need migrations, for example when capacitor 5 was released it required plugin developers to migrate their plugins to capacitor 5. Capcitor 5 comes with benefits though.
are you uploading image as base64, setting android:largeHeap="true" basically means hey android give my app more heap space and andoird be like “Ok I will try, but I can’t promise”?
Because the project (angular/capacitorjs) I’m currently working we upload short videos. We did testing and some iOS devices could upload 30-40MBs and Android up to 60MBs. As a result we just set MAX_UPLOAD_SIZE to 30MB on client side.
@sultanmyrza thanks for the info! We might try the cordova plugin, but only if needed. Very interesting that you are able to upload 30MB! What sort of request do you use for that? A Http POST request with the Capacitor Http plugin? How is the data formatted?
are you uploading image as base64
Yes, I tried both a base64 string and I tried a FormData. Both work on web and android but fail on iOS.
are you setting android:largeHeap=“true”
Yes we did this. On Android no issues currently. But on iOS a 2MB file fails as described below
Is it crashing the app? / is you backend returning error?
No for both questions. It silently refuses to make a HTTP request. The javascript code that executes fetch is called. The Capacitor Http plugin logs the request:
But then nothing else happens. The backend never receives the request. And even more strange, the catch() and then() clauses are never called. No error. Nothing.
I don’t know about the interiors of the HTTP API, however I’m fairly familiar with the native fetch API. When uploading a file as a POST value the size is limited. However when sending it in the body of the request, large files can be uploaded without issues. Try this code:
fetch('your-server-side-script', {
method: 'POST',
body: image_to_be_uploaded
}).then(response => {
return response.text()
}).then(text => {
console.log(text);
// do anything you like with the response
});
Would you mind to post the code that does this?
And the output in the network tab of the developer tools.
However, there might be restrictions on iOS I don’t know about.