Expo and uploading image Blobs?

Sure: https://gist.github.com/allpwrfulroot/7539e58ad6a8258d78e8f4808f513cad

Not a pure answer to the question, but my adaptation of notbrent’s examples and some GraphQL docs to get and upload an image to a server. Getting the correct FormData takes some experimentation and depends on the server / service you’re using; if your docs provide a cURL example that’s where to start?

Thanks! I will try to understand that code, but I think my comprehension of it is limited at best ATM

The example you gave was for uploading to s3, can you do the same thing with the new firebase functions?

yup, you can, I don’t have a link to an example app to do it but I’ve heard of Expo users doing it before. if you can create an example app for that it would be neat!

1 Like

You can upload with firebase by converting the uri to Uint8Array using XMLHttpRequest - only tested on IOS so far

This solution ultimately did not work so I am just converting the base64 string to a ByteArray in code for both IOS and Android and I can get the file uploading working with firebase - https://github.com/aaronksaunders/expo-rn-firebase-image-upload/blob/master/README.md

8 Likes

Wow. I have just tried this and it works perfect! Thank you.

1 Like

I tried your example and while its exactly what I’ve been looking for, I can’t seem to get the base64 from the ImagePicker. I’m passing in base64: true into the object parameter for launchImageLibraryAsync, but there is no base64 to come out in my project for some reason, only in yours. So my pickerResult.base64 is coming out null.

1 Like

what sdk version are you using? this only works on sdk18+

2 Likes

That’ll do it. Updating now. Fingers crossed for no breaking changes.

If I have a published version of my app on the app stores and I update from 17 to 18 sdk do I need to update the app from the app stores or can I do it from expo with publish?

it depends when you did the standalone build – if you did it after we released sdk 18 then you should be fine. if you publish a sdk 18 version of your app and notice that it’s not getting used when you restart the standalone build, then you need to rebuild it. see the limitations section of our publishing guide

1 Like

Aaron, I tried your solution and everything seems to make a lot of sense, but for some reason when I pass in the base64 string to this.convertToByteArray(pickerResult.base64), I get the following error: Error: ‘atob’ failed: The string to be decoded is not correctly encoded.

Do you have any idea why’s that happening?

Edit: I ended up ditching your atob function for the decode() method from base-64 library and it all worked !!

glad it worked for you, where is the base64 library that you used? it might be helpful to others who run into issues with the implementation I presented here?

This one GitHub - mathiasbynens/base64: A robust base64 encoder/decoder that is fully compatible with `atob()` and btoa()`, written in JavaScript.

2 Likes

Wow! works! thank you so much!

This solution worked really well for me for a while, but eventually I started getting these errors:

FirebaseStorageError {
  "code_": "storage/retry-limit-exceeded",
  "column": 29,
  "line": 12091,
  "message_": "Firebase Storage: Max retry time for operation exceeded, please try again.",
  "name_": "FirebaseError",
  "serverResponse_": null,
  "sourceURL": "http://192.168.0.102:19002/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=true&minify=false",
}

It happens every time on all but the smallest images. I don’t think my Firebase storage is full, but I’m not sure how to check.

Recently, your solution worked nicely in IOS but when I try this in android, it won’t work.
Error message is as below.

Possible Unhandled Promise Rejection (id: 0):
FirebaseStorageError {
“code_”: “storage/retry-limit-exceeded”,
“column”: 29,
“line”: 12256,
“message_”: “Firebase Storage: Max retry time for operation exceeded, please try again.”,
“name_”: “FirebaseError”,
“serverResponse_”: null,
“sourceURL”: “http://192.168.43.237:19001/main.bundle?platform=android&dev=true&hot=false&minify=false”,
}

It works just fine in IOS but not in Android. Can you please tell me about this?

I have same problem in android, but I think if don’t allow user to edit the pic which means set allowsEditing=false, then it works fine. Still need to dig out why is that though.

I already set allowsEditing=false but still not working in Android …