React Native: Trouble with multipart/form-data uploads to Google Drive API

Hey everyone! I’m stuck with a tricky problem in my React Native app. I’m trying to upload files to Google Drive using their API, but I keep hitting a wall.

The weird thing is, when I use Postman to send the request, it works perfectly. But when I try to do the same thing in my app using fetch or axios, I get this frustrating ‘Malformed multipart body’ error.

I’m using FormData to build the request, adding both metadata and the file. I’ve double-checked everything, and it matches what works in Postman. So I’m thinking maybe React Native handles FormData or the Content-Type header differently?

Has anyone run into this before? Any tips on how to make FormData work the same way in React Native as it does in Postman? Or maybe there’s a better way to send these kinds of requests in React Native?

I’d really appreciate any help or ideas. Thanks!

Here’s a simplified version of what I’m trying:

const sendFile = async () => {
  const form = new FormData();
  form.append('metadata', JSON.stringify({
    name: 'myFile.txt',
    mimeType: 'text/plain'
  }));
  form.append('file', {
    uri: fileUri,
    type: 'text/plain',
    name: 'myFile.txt'
  });

  try {
    const response = await fetch('https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${accessToken}`,
      },
      body: form
    });
    // Handle response
  } catch (error) {
    console.error('Upload failed:', error);
  }
};

Any thoughts?

I’ve faced similar issues with multipart/form-data uploads in React Native before. It can be tricky because RN’s implementation of FormData doesn’t always play nice with certain APIs.

One workaround that worked for me was using the ‘react-native-blob-util’ library. It gives you more control over how the multipart request is constructed. Here’s a rough idea of how you might adapt your code:

import RNFetchBlob from 'react-native-blob-util';

const sendFile = async () => {
  const metadata = JSON.stringify({
    name: 'myFile.txt',
    mimeType: 'text/plain'
  });

  try {
    const response = await RNFetchBlob.fetch('POST', 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart', {
      Authorization: `Bearer ${accessToken}`,
      'Content-Type': 'multipart/form-data'
    }, [
      { name: 'metadata', data: metadata, type: 'application/json' },
      { name: 'file', filename: 'myFile.txt', data: RNFetchBlob.wrap(fileUri) }
    ]);
    // Handle response
  } catch (error) {
    console.error('Upload failed:', error);
  }
};

This approach gives you more fine-grained control over how the multipart request is structured. It might solve your ‘Malformed multipart body’ issue. Give it a shot and let me know if it helps!

I encountered a similar issue when working with multipart/form-data in React Native. One solution that worked for me was using the ‘react-native-document-picker’ library in combination with ‘react-native-fs’. This approach allows for better file handling and more accurate mime type detection.

Here’s a basic implementation:

import DocumentPicker from 'react-native-document-picker';
import RNFS from 'react-native-fs';

const sendFile = async () => {
  try {
    const res = await DocumentPicker.pick({
      type: [DocumentPicker.types.allFiles],
    });
    
    const fileContent = await RNFS.readFile(res[0].uri, 'base64');
    
    const form = new FormData();
    form.append('metadata', JSON.stringify({
      name: res[0].name,
      mimeType: res[0].type
    }));
    form.append('file', fileContent, res[0].name);

    // Your fetch request here...
  } catch (err) {
    if (DocumentPicker.isCancel(err)) {
      // User cancelled the picker
    } else {
      throw err;
    }
  }
};

This method ensures that the file is properly read and its mime type is correctly identified, which could resolve the ‘Malformed multipart body’ error you’re experiencing.

yo, i had the same prob. try usin the ‘react-native-fs’ library. it handles file stuff better in RN. u can read the file as a blob and send it. somethin like this:

import RNFS from 'react-native-fs';

// Read file
const fileContent = await RNFS.readFile(fileUri, 'base64');

// Then in ur form data
form.append('file', fileContent, 'myFile.txt');

hope this helps! lemme kno if u need more info