eclipsesource / eclipsesource/tabris-js
Issue with uploading photos taken on the camera using fetch()
- Dominant language
- JavaScript
- Stars
- 1.4k
- Forks
- 171
- PR merge metrics
- No merged PRs in 30d
Description
### Problem description
Attempting to use `fetch()` with `FormData()` containing a blob for a photo taken on the device fails on Android, but works on iOS.
### Expected behavior
`fetch()` should succeed and upload the photo.
### Environment
- Tabris.js version: 3.7.2
- Device: Samsung Galaxy A40 (and Honor 10)
- OS: Android 11
### Code snippet
```js
let captured_pod_image = await camera.captureImage({flash: 'auto'});
let image = captured_pod_image.image;
let formData = new FormData();
formData.append("image", new Blob([image.arrayBuffer()], {type: image.type}), "some_image.jpg");
console.log("About to fetch");
// Make API request to confirm completion
const response = await fetch(
'http://bla/some/url (http on tabris dev app, https on our build)',
{
method: 'POST',
headers: {/* redacted */},
body: formData
}
);
console.log("Done fetch");
if (!response.ok) {
console.log("Fetch not OK");
return;
}
console.log("Fetch OK");
```
Now, the strange thing is that it works perfectly on iOS, but fails on Android. With iOS, we get this output:
```
About to fetch
Done fetch
Fetch OK
```
And with Android, we get:
```
About to fetch
> Listener for Button event "tap" rejected: TypeError: Network request failed
at onTap (/xxxx/src/xxx.tsx:946:92)
```
Is this an issue with Tabris itself, or am I doing something wrong? I’d really appreciate any help. Thanks
The real flow does in fact have a step in the middle where the image is shown back to the user to be confirmed before it gets bundled into the FormData and the image shows fine there on both all devices
In case it’s of use, I have tried (I know it’s less good and not plan A) to base64 encode the image and put it in a JSON body to post to the API, with code like:
```js
function arrayBufferToBase64(buffer) {
var binary = '';
var bytes = new Uint8Array(buffer);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[ i ]);
}
return btoa(binary);
}
```
This works perfectly on iOS too, it works perfectly on an Android Honor 10, and very strangely it works about 20% of the time on a Samsung Galaxy A40, the remainder of the time the resulting base64 string is entirely number ones - 11111111…
Maybe there is an issue with the arrayBuffer on Android?
Contributor guide
Assessment
This issue has not been assessed yet.