0

I'm trying to upload an xlsx to Firestore storage, using react-native-document-picker to pick the file from ExternalStorageDirectoryPath so when I just log the files URI I don't get the error but as soon as try to upload the file it throws the error.

relevant code :

const uploadFile = async () => {
  try {
    const res = await DocumentPicker.pick({
      type: [DocumentPicker.types.allFiles],
    });
           
    const task = Storage().ref('catalogue/'+ res.name).putFile(res.uri);
           
    task.on('state_changed', 
      sn => {},
      err => console.log(err),
      () => {
        console.log('excel uploaded!'+res.name)
        Storage()
          .ref("catalogue").child(res.name).getDownloadURL()
          .then(url => {
            console.log('uploaded excel url', url);
          }).catch(err=>console.log(err))
      }
    )
    await task 
           
  } catch (err) {
    if (DocumentPicker.isCancel(err)) {
      // User cancelled the picker, exit any dialogs or menus and move on
    } else {
      throw err;
    }
  }
}

I already included the required permissions in myAndroidManifest.xml` file and rebuilt the project

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS"/>

but still I'm getting this error:

Permission Denial: reading com.android.externalStorageProvider uri content://com... requires android.permission.MANAGE_DOCUMENTS, or grantUriPermission()

greybeard
  • 2,249
  • 8
  • 30
  • 66
سعيد
  • 1,547
  • 1
  • 14
  • 32
  • There are two AndroidManifest files in react-native. Double check that you have it in the root file, and also, it might be worth doing a clean install of the app or checking it's permissions granted in the settings. – nipuna-g Feb 15 '21 at 00:48
  • This answer may help you https://stackoverflow.com/a/60316149/7178860 – Mohammad Feb 15 '21 at 06:23

3 Answers3

3

Here is my code that solved this issue:

handleFileSelection = async (props) => {
  try {
    const response = await DocumentPicker.pickMultiple({
      presentationStyle: "fullScreen",
      allowMultiSelection: true,
      copyTo: "cachesDirectory",
    });
    await this.pickImageAndUpload(response[0].fileCopyUri);
  } catch (err) {
    console.warn(err);
  }
};

pickImageAndUpload = async (uri) => {
  const uploadTask = storage()
    .ref()
    .child(`/usersChatImages/${Date.now()}`)
    .putFile(uri);
  uploadTask.on(
    "state_changed",
    (snapshot) => {
      var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
    },
    (error) => {
      alert("error uploading image");
    },
    () => {
      uploadTask.snapshot.ref
        .getDownloadURL()
        .then((downloadURL) => {
          alert(downloadURL);
        })
        .catch((err) => {
          alert("YESSS");
        });
    }
  );
};
DinhNguyen
  • 303
  • 2
  • 14
2

I had a similar problem with the frameworks Qt with the last android SDK version, I've fixed the problem by adding requestLegacyExternalStorage in the manifest (pat Application):

<application
  android:requestLegacyExternalStorage="true"
  android:hardwareAccelerated="true" 
  android:name="org.qtproject.qt5.android.bindings.QtApplication" 
  //...
/>

it's related to a recent change in the permission system: https://developer.android.com/about/versions/11/privacy/storage

DinhNguyen
  • 303
  • 2
  • 14
Antoine Laps
  • 111
  • 5
0
const res = await DocumentPicker.pickSingle({
  type: [DocumentPicker.types.allFiles],
  copyTo: 'cachesDirectory',
});

let fileCopyUri = res.fileCopyUri
const filename = fileCopyUri.substring(fileCopyUri.lastIndexOf('/') + 1);
const task = storage().ref(filename).putFile(fileCopyUri);

//  add "copyTo: 'cachesDirectory'",
//  add res.fileCopyUri
muthu raja
  • 26
  • 2