File upload with DocumentPicker in Android.

Hi guys,

I am trying to upload a file that chosen from Document Picker, Image Picker or directly from Camera. I get the files’ URI from expo and using multipart and fetch function to send the data. In iOS, everything works as expected. In Android, Image Picker and Camera is working as expected. However, Document Picker is not working. I am getting a network failed for files that chosen from Document Picker.

Hey @popleads,

Sorry you’re having trouble with this. Could you provide some more information pertaining to the problem such as what SDK version you are running, if this is occurring on a simulator or physical device, if the latter which device(s) and ideally creating a MCVE using Snack so that we can try and debug this on our end?

Cheers,

Adam

Hi @adamjnav,

I do not know how to create on Snack. However I can give you some information. I tried on both simulator and physical device that runs on Android 7.
This is a part of my package.json

    "expo": "^31.0.2",
    "react": "16.5.0",
    "react-native": "https://github.com/expo/react-native/archive/sdk-31.0.0.tar.gz",

And the code that I am using:

async pickFromDocument() {
    const result = await DocumentPicker.getDocumentAsync({});
    if (!result.cancelled && result.type !== 'cancel' ) {
      this.props.addDocument({ document: result, isFromStorage: true });
      this.setState({ isModal: false });
    }
  }

addDocument method comes from redux-actions and this is the method.

export const addDocument = ({ document, isFromStorage }) => {
   return (dispatch) => {
     let filename;
     let type;
     if (isFromStorage) {
       filename = document.name;
       type = document.name.split('.').reverse()[0];
     } else {
       filename = document.uri.split('/').pop();
       const match = /\.(\w+)$/.exec(filename);
       type = match ? `image/${match[1]}` : `image`;
     }
     const details = {
      fn: 'uploadAttachment',
      file: { uri: document.uri, name: filename, type }
    };

    const callback = () => {
      // DO SOMETHING FOR HANDLING THE SERVER REQUEST RESPONSE
    };
    const formBody = ServerStat.makeData(details);
    ServerStat.fetchData('uploadAttachment', formBody, callback.bind(this));
  };
 };

and the makeData, fetchData methods:

makeData(details) {
    var formData = new FormData();
    for(var k in details){
      if (details[k] instanceof Array) {
        for (var detail in details[k]) {
          formData.append(k + '[]', details[k][detail]);
        }
      } else {
        formData.append(k, details[k]);
      }
    }
    return formData;
  },

async fetchData(func, data, callback, isFromLogin) {
    var result = '';
    await fetch(SERVER_END_POINT + '/ws/' + func, {
        method: 'POST',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'multipart/form-data; charset=UTF-8',
        },
        body: data
      }).then((response) => response.json())
      .then((responseJson) => {
        if (responseJson.stat === ServerStat.OK) {
          result = responseJson;
          callback(result);
        } else if (responseJson.stat === ServerStat.NOK_NOT_LOGGED_IN) {
          result = 'Login'
          Actions.auth();
        } else {
          result = 'nok'
          if (isFromLogin) {
            callback(result);
          }
          this.showAlert(responseJson.text);
        }
    }).catch((error) => {
      result = 'Error';
      console.log(error);
      this.showAlert(ServerStat.ERROR);
    });
  },

Anything on this? This is kind of important…

2 Likes

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.