eclipsesource / eclipsesource/tabris-js

Issue with uploading photos taken on the camera using fetch()

Open
#2,192 6 comments 0 reactions 0 assignees View on GitHub
bug
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.