How to Upload Image From React Native To Express Server? - express

I am trying to upload a photo from an ios phone to an express server and I cannot seem to send the file to the server correctly. I am using react-native-image-picker and that gives me access to the photo's uri (location on the mobile phone). I am then trying to send that to the server like this:
const data = new FormData();
data.append('name', 'testName');
data.append('photo', {
uri: imageUriString,
type: 'image/jpeg',
name: 'testPhotoName'
});
I am then making a post request to the server with the body of the request being data.
The problem is that on the server side I am not getting the actual file. Instead I am getting the imageUriString which I cannot do anything with.
My req.files is undefined in the endpoint. (And I am parsing multipart/form-data so that is not the problem).
How do I upload the actual photo from React Native and receive it in req.file in Express?

I believe that you have to use var or let instead of const when using FormData. Reason being, since you are appending data to the variable, it needs to be able to change the contents of the variable's memory.

Related

React Native `Formdata` is not able to send data to backend due to {_parts}

i don't know why in react native formData use to send data in {_parts} and that gives response for data field as this field is required with 400 error...
in backend it not able to receive in {_parts}
have anyone go through this issue please let me know I am stuck in this since 1week.. but working fine in web application using formData it simply goes like the given image
It works like that so its normal
React Native Form Data is used to send form data which also includes files so when using with FormData, set header 'Content-Type':'multipart/formdata' and i think you backend should understand this.
Refer the link below which is article to how send data in react native which also has backend code in Node and Express.
This Link
This Should get you idea clear.

React Native - Network request failed when uploading image second time

I have found what seems to be a bug on Android. I have not tested it on IOS.
updateProfilePhoto() is a redux thunk that just sends a PUT request to my node server.
The problem is this, I can upload an image to my node server using fetch. The image is received and saved successfully on the server. If I wait for about 1 second and the upload another image, it goes through successfully. However, if I upload an image and then upload another immediately after the first one goes through, I get the error 'Network request failed' and the second image will not be received on the server.
It seems to me that I cannot constantly upload images back to back really quickly, one will go through, the next one will fail and the next will go through... and so on.
I am testing on an Android Emulator. API level 30. I have not tested on a real device yet, I will try that when I'm able to.
The error happens for the built-in fetch() and XMLHttpRequest. Both behave the same. On XMLHttpRequest I can check the progress and it says 100% and then fails with xhr.status equal to 0.
I need a sure fire way to upload an image to my server without it failing for no reason. I can add a delay of something like 500ms between uploads and show the user that it's loading but that's a silly way to resolve the issue. I can't find out why the upload fails on the second try.
const onSelectProfileImage = (pickerResponse: ImagePickerResponse) =>
{
const uri = pickerResponse?.assets && pickerResponse.assets[0].uri;
const name = pickerResponse?.assets && pickerResponse.assets[0].fileName;
const type = pickerResponse?.assets && pickerResponse.assets[0].type;
if(uri)
{
const photo = new FormData();
photo.append('photo', {name,type,uri});
dispatch(updateProfilePhoto({photo, uri, user_id: id, headers: {...headers,"content-type": "multipart/form-data"}}))
}
}

How to send local image to chat using incoming webhook

Facing issue while send the local image to google chat room using web hook.
attachment = open("images.jpg", "rb")
bot_message = {"cards": [{ "sections": [{"widgets": [{"image": attachment}]}]}]}
print (bot_message)
message_headers = {'Content-Type': 'application/json; charset=UTF-8'}
Error:
TypeError: Object of type BufferedReader is not JSON serializable
Issue roots from BufferedReader not JSON serializable which is caused by image widget expecting a URL instead.
Alternative is that, you need to upload your file to an image hosting site first (e.g. imgur) and then use the url of the posted image to the image widget's image url. For this one, see Imgur API docs.
Reference:
Image Widget requiring URL
uploading a file to imgur via python

PHAsset image URI for react native application

I'm writing a native iOS component for react native to fetch PHAsset(s) from camera roll. I'm struggling to show an upload a PHAsset as it's not giving a proper URI to use in react native and I'm writing an upload component too. How to achieve this.
I have solved this using the expo-media-library
https://docs.expo.io/versions/latest/sdk/media-library
async myFunc() {
let uri = "ph://ED7AC36B-A150-4C38-BB8C-B6D696F4F2ED/L0/001"
let myAssetId = uri.slice(5);
let returnedAssetInfo = await MediaLibrary.getAssetInfoAsync(myAssetId);
console.log(returnedAssetInfo.localUri); // you local uri link to get the file
} }`
React Native currently has very mixed support for PHAsset (aka PHImageLibrary) URIs, eg photos://A6A2CEBD-766E-4BD7-980C-71ED7828674E/L0/001. It has much better support for the deprecated ALAssetsLibrary eg assets-library://asset/asset.MOV?id=A6A2CEBD-766E-4BD7-980C-71ED7828674E&ext=MOV (note that is a video, not a photo, but the idea is the same).
You'll notice the ID in there is the same, it's just prefix/suffix changes. Try string manipulating that yourself.
Also, basically nothing supports a local URI that isn't prepended by photos:// or assets-library://. PHAssets don't have that, because ~~~apple things~~~. Try prepending photos://.
Side note, these URIs will work for things in iCloud that aren't actually local.

Trouble uploading media (images) to twilio programmable chat in react-native

I'm implementing programmable-chat in react-native using the npm package. Unfortunately, I'm stuck on being able to correctly upload messages with images to twilio. The twilio js documentation outlines 3 ways to create a Media Message. Sending: 1) FormData (doesn't seem applicable to me in react-native?), 2) a String, or 3) a Buffer.
I've tried many variations at this point and am stumped. I've been all over the place with both react-native-fs and react-native-fetch-blob and haven't cracked it yet.
Everything I try results in failure or in a String being uploaded. When the String is uploaded, I can complete a round trip by fetching the created Media Message, getting the the temporary url of the media attachment, manually fetching the String stored at that url, and then crafting a base64 data uri for the Image element with the fetched String. But I'm 99% sure that is 'doing it wrong'. If I do it right, Twilio should be storing an actual image for me and giving me a temporary url that I can directly feed to my Image element, right?
To sum up: I can get a base64 encoded string to be stored in twilio, but for the life of me I can't figure out how to get the image binary up there so as to be directly accessible when hitting the url it is at.
I feel like I've got to be missing something simple, but I'm out of ideas at the moment. Is there a way to get a Buffer set up in react native? Should I be trying something with FormData?
I finally figured this out. This was just a problem not knowing how to get the file into a buffer in react native. I was finally able to get this working with a combination of react-native-fs and buffer. The code looks something like:
import RNFS from 'react-native-fs'
myMethod(twilioChannelObject, filePathString) {
RNFS.readFile(filePath, 'base64').then((data) => {
var Buffer = require('buffer/').Buffer
data = Buffer.from(data, 'base64')
twilioChannelObject.sendMessage({
contentType: 'image/png',
media: data
}).then(id => {})
})
}
This probably isn't the best practice way to solve the problem, but it got it to work for me, so moving on for now.