React-native-document-picker: Permission Denial Error when trying to upload file picked from ExternalStorageDirectoryPath to fireStore storage

Created on 8 Feb 2021  路  10Comments  路  Source: rnmods/react-native-document-picker

I'm trying to upload a .xlsx file to firestore storage ,I'm using react-native-document-picker to pick the file from ExternalStorageDirectoryPath so when 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],
            });
            console.log(res.uri) //<-----works fine

            //this is what iscausing the error apparently 
            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 my AndroidManifest.xml file and rebuilt the project , although From what I've read, MANAGE_DOCUMENTS is a "signature" permission and cannot be added to the manifest.xml or granted by the react native android permission API.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MANAGE_DOCUMENTS"/>
the Error I'm getting :

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

help wanted

Most helpful comment

exist another post about this, recently i found this packages as alternative to rn-fetch-blob

https://github.com/flyerhq/react-native-android-uri-path

it works for me

All 10 comments

Screenshot_1612974550

Im facing same issue here someone please help us please.

Upload to Firebase Storage

storageRef.putFile(file.uri).then(function(snapshot) {
            storageRef.getDownloadURL().then(function(url) {
                file.public_url = url //merge public url to file object
                console.log(url)
            }).catch(function(error) {
                console.log("error at storageRef.putFile() ", error)
            });
        }).catch(function(e) {
            console.log("Upload Error ", e)
        });

Screenshot_1612974550

Im facing same issue here someone please help us please.

Upload to Firebase Storage

storageRef.putFile(file.uri).then(function(snapshot) {
            storageRef.getDownloadURL().then(function(url) {
                file.public_url = url //merge public url to file object
                console.log(url)
            }).catch(function(error) {
                console.log("error at storageRef.putFile() ", error)
            });
        }).catch(function(e) {
            console.log("Upload Error ", e)
        });

its really annoying that we have to deal with this

hello @Saidfatah

its really annoying that we have to deal with this

you're more than welcome to investigate this and open a PR with a fix, it'll be appreciated, thank you

If the solution below doesn't work, have a look at other comment. It perfectly works :

https://github.com/rnmods/react-native-document-picker/issues/387#issuecomment-790977119

Firebase Storage is not suitable with content://com uri.

So firstly do npm install --save rn-fetch-blob https://github.com/joltup/rn-fetch-blob thenimport RNFetchBlob from 'rn-fetch-blob';

After that use this function below to get the uri which is suitable for firebase storage

getPathForFirebaseStorage = async(uri) => {
        if (Platform.OS === 'ios')
        {
            return uri
        } 
        const stat = await RNFetchBlob.fs.stat(uri)
        return stat.path
}

stat.path returns "data/0/..." path for the given uri.

At the end have a look at the main code below

 const documentUri= await this.getPathForFirebaseStorage(document.uri)
 const storageRef = firebase.storage().ref();
 await storageRef
                    .child( '/documents/' + document.name)
                    .putFile(documentUri).then((snapshot) => {
                        console.log('has been successfully uploaded.');
                    }).catch((e) => console.log('uploading image error => ', e));                   

We get the suitable uri from this.getPathForFirebaseStorage(document.uri) function. document.uri is res.uri in your code and that function returns a new uri which is called as documentUri. Put the documentUri to the storage function.

Briefly ;
1- just add the getPathForFirebaseStorage function.
2- After the line console.log(res.uri) //<-----works fine,
add
const documentUri= await this.getPathForFirebaseStorage(res.uri)
3- Change the parameter res.uri -> documentUri in putFile :
const task = Storage().ref('catalogue/'+ res.name).putFile(documentUri);

I think it works. I have faced with that problem and RNFetchBlob solved it.

Reference : https://github.com/invertase/react-native-firebase/issues/2558#issuecomment-534955902Link

exist another post about this, recently i found this packages as alternative to rn-fetch-blob

https://github.com/flyerhq/react-native-android-uri-path

it works for me

Firebase Storage is not suitable with content://com uri.

So firstly do npm install --save rn-fetch-blob https://github.com/joltup/rn-fetch-blob thenimport RNFetchBlob from 'rn-fetch-blob';

After that use this function below to get the uri which is suitable for firebase storage

getPathForFirebaseStorage = async(uri) => {
        if (Platform.OS === 'ios')
        {
            return uri
        } 
        const stat = await RNFetchBlob.fs.stat(uri)
        return stat.path
}

stat.path returns "data/0/..." path for the given uri.

At the end have a look at the main code below

 const documentUri= await this.getPathForFirebaseStorage(document.uri)
 const storageRef = firebase.storage().ref();
 await storageRef
                    .child( '/documents/' + document.name)
                    .putFile(documentUri).then((snapshot) => {
                        console.log('has been successfully uploaded.');
                    }).catch((e) => console.log('uploading image error => ', e));                   

We get the suitable uri from this.getPathForFirebaseStorage(document.uri) function. document.uri is res.uri in your code and that function returns a new uri which is called as documentUri. Put the documentUri to the storage function.

Briefly ;
1- just add the getPathForFirebaseStorage function.
2- After the line console.log(res.uri) //<-----works fine,
add
const documentUri= await this.getPathForFirebaseStorage(res.uri)
3- Change the parameter res.uri -> documentUri in putFile :
const task = Storage().ref('catalogue/'+ res.name).putFile(documentUri);

I think it works. I have faced with that problem and RNFetchBlob solved it.

Reference : invertase/react-native-firebase#2558 (comment)

When doing that I get this error:

Error: [storage/unknown] /storage/emulated/0/Download/3497-normal.jpg: open failed: EACCES (Permission denied)
NativeFirebaseError: [storage/unknown] /storage/emulated/0/Download/3497-normal.jpg: open failed: EACCES (Permission denied)

Despite having requested READ_EXTERNAL_STORAGE with the PermissionsAndroid API (and it's also set in the AndroidManifest). For now I'm using a solution I read here, but as someone else said later in that thread, it takes up a lot of memory for large files.

Firebase Storage is not suitable with content://com uri.
So firstly do npm install --save rn-fetch-blob https://github.com/joltup/rn-fetch-blob thenimport RNFetchBlob from 'rn-fetch-blob';
After that use this function below to get the uri which is suitable for firebase storage

getPathForFirebaseStorage = async(uri) => {
        if (Platform.OS === 'ios')
        {
            return uri
        } 
        const stat = await RNFetchBlob.fs.stat(uri)
        return stat.path
}

stat.path returns "data/0/..." path for the given uri.
At the end have a look at the main code below

 const documentUri= await this.getPathForFirebaseStorage(document.uri)
 const storageRef = firebase.storage().ref();
 await storageRef
                    .child( '/documents/' + document.name)
                    .putFile(documentUri).then((snapshot) => {
                        console.log('has been successfully uploaded.');
                    }).catch((e) => console.log('uploading image error => ', e));                   

We get the suitable uri from this.getPathForFirebaseStorage(document.uri) function. document.uri is res.uri in your code and that function returns a new uri which is called as documentUri. Put the documentUri to the storage function.
Briefly ;
1- just add the getPathForFirebaseStorage function.
2- After the line console.log(res.uri) //<-----works fine,
add
const documentUri= await this.getPathForFirebaseStorage(res.uri)
3- Change the parameter res.uri -> documentUri in putFile :
const task = Storage().ref('catalogue/'+ res.name).putFile(documentUri);
I think it works. I have faced with that problem and RNFetchBlob solved it.
Reference : invertase/react-native-firebase#2558 (comment)

When doing that I get this error:

Error: [storage/unknown] /storage/emulated/0/Download/3497-normal.jpg: open failed: EACCES (Permission denied)
NativeFirebaseError: [storage/unknown] /storage/emulated/0/Download/3497-normal.jpg: open failed: EACCES (Permission denied)

Despite having requested READ_EXTERNAL_STORAGE with the PermissionsAndroid API (and it's also set in the AndroidManifest). For now I'm using a solution I read here, but as someone else said later in that thread, it takes up a lot of memory for large files.

well thankyou or the suggestion in my case my files are very small 1mb to 20mb

Firebase Storage is not suitable with content://com uri.
So firstly do npm install --save rn-fetch-blob https://github.com/joltup/rn-fetch-blob thenimport RNFetchBlob from 'rn-fetch-blob';
After that use this function below to get the uri which is suitable for firebase storage

getPathForFirebaseStorage = async(uri) => {
        if (Platform.OS === 'ios')
        {
            return uri
        } 
        const stat = await RNFetchBlob.fs.stat(uri)
        return stat.path
}

stat.path returns "data/0/..." path for the given uri.
At the end have a look at the main code below

 const documentUri= await this.getPathForFirebaseStorage(document.uri)
 const storageRef = firebase.storage().ref();
 await storageRef
                    .child( '/documents/' + document.name)
                    .putFile(documentUri).then((snapshot) => {
                        console.log('has been successfully uploaded.');
                    }).catch((e) => console.log('uploading image error => ', e));                   

We get the suitable uri from this.getPathForFirebaseStorage(document.uri) function. document.uri is res.uri in your code and that function returns a new uri which is called as documentUri. Put the documentUri to the storage function.
Briefly ;
1- just add the getPathForFirebaseStorage function.
2- After the line console.log(res.uri) //<-----works fine,
add
const documentUri= await this.getPathForFirebaseStorage(res.uri)
3- Change the parameter res.uri -> documentUri in putFile :
const task = Storage().ref('catalogue/'+ res.name).putFile(documentUri);
I think it works. I have faced with that problem and RNFetchBlob solved it.
Reference : invertase/react-native-firebase#2558 (comment)

When doing that I get this error:

Error: [storage/unknown] /storage/emulated/0/Download/3497-normal.jpg: open failed: EACCES (Permission denied)
NativeFirebaseError: [storage/unknown] /storage/emulated/0/Download/3497-normal.jpg: open failed: EACCES (Permission denied)

Despite having requested READ_EXTERNAL_STORAGE with the PermissionsAndroid API (and it's also set in the AndroidManifest). For now I'm using a solution I read here, but as someone else said later in that thread, it takes up a lot of memory for large files.

You can also try that :

npm i @flyerhq/react-native-android-uri-path

import getPath from '@flyerhq/react-native-android-uri-path';

const imageUri = getPath(image.uri);
                            await storageRef
                                .child(image.name)
                                .putFile(imageUri).then((snapshot) => {
                                    console.log('Image has been successfully uploaded.')
                                }).catch((e) => console.log('uploading image error => ', e));

Firebase Storage is not suitable with content://com uri.
So firstly do npm install --save rn-fetch-blob https://github.com/joltup/rn-fetch-blob thenimport RNFetchBlob from 'rn-fetch-blob';
After that use this function below to get the uri which is suitable for firebase storage

getPathForFirebaseStorage = async(uri) => {
        if (Platform.OS === 'ios')
        {
            return uri
        } 
        const stat = await RNFetchBlob.fs.stat(uri)
        return stat.path
}

stat.path returns "data/0/..." path for the given uri.
At the end have a look at the main code below

 const documentUri= await this.getPathForFirebaseStorage(document.uri)
 const storageRef = firebase.storage().ref();
 await storageRef
                    .child( '/documents/' + document.name)
                    .putFile(documentUri).then((snapshot) => {
                        console.log('has been successfully uploaded.');
                    }).catch((e) => console.log('uploading image error => ', e));                   

We get the suitable uri from this.getPathForFirebaseStorage(document.uri) function. document.uri is res.uri in your code and that function returns a new uri which is called as documentUri. Put the documentUri to the storage function.
Briefly ;
1- just add the getPathForFirebaseStorage function.
2- After the line console.log(res.uri) //<-----works fine,
add
const documentUri= await this.getPathForFirebaseStorage(res.uri)
3- Change the parameter res.uri -> documentUri in putFile :
const task = Storage().ref('catalogue/'+ res.name).putFile(documentUri);
I think it works. I have faced with that problem and RNFetchBlob solved it.
Reference : invertase/react-native-firebase#2558 (comment)

When doing that I get this error:

Error: [storage/unknown] /storage/emulated/0/Download/3497-normal.jpg: open failed: EACCES (Permission denied)
NativeFirebaseError: [storage/unknown] /storage/emulated/0/Download/3497-normal.jpg: open failed: EACCES (Permission denied)

Despite having requested READ_EXTERNAL_STORAGE with the PermissionsAndroid API (and it's also set in the AndroidManifest). For now I'm using a solution I read here, but as someone else said later in that thread, it takes up a lot of memory for large files.

well thankyou or the suggestion in my case my files are very small 1mb to 20mb

You can have a look at that comment, it perfectly works. I changed my rn-fetch code to that one. I think it is good for your error

https://github.com/rnmods/react-native-document-picker/issues/387#issuecomment-790977119

If the solution below doesn't work, have a look at other comment. It perfectly works :

#387 (comment)

Firebase Storage is not suitable with content://com uri.

So firstly do npm install --save rn-fetch-blob https://github.com/joltup/rn-fetch-blob thenimport RNFetchBlob from 'rn-fetch-blob';

After that use this function below to get the uri which is suitable for firebase storage

getPathForFirebaseStorage = async(uri) => {
        if (Platform.OS === 'ios')
        {
            return uri
        } 
        const stat = await RNFetchBlob.fs.stat(uri)
        return stat.path
}

stat.path returns "data/0/..." path for the given uri.

At the end have a look at the main code below

 const documentUri= await this.getPathForFirebaseStorage(document.uri)
 const storageRef = firebase.storage().ref();
 await storageRef
                    .child( '/documents/' + document.name)
                    .putFile(documentUri).then((snapshot) => {
                        console.log('has been successfully uploaded.');
                    }).catch((e) => console.log('uploading image error => ', e));                   

We get the suitable uri from this.getPathForFirebaseStorage(document.uri) function. document.uri is res.uri in your code and that function returns a new uri which is called as documentUri. Put the documentUri to the storage function.

Briefly ;
1- just add the getPathForFirebaseStorage function.
2- After the line console.log(res.uri) //<-----works fine,
add
const documentUri= await this.getPathForFirebaseStorage(res.uri)
3- Change the parameter res.uri -> documentUri in putFile :
const task = Storage().ref('catalogue/'+ res.name).putFile(documentUri);

I think it works. I have faced with that problem and RNFetchBlob solved it.

Reference : https://github.com/invertase/react-native-firebase/issues/2558#issuecomment-534955902[Link](https://github.com/rnmods/react-native-document-picker/issues/387#issuecomment-790977119)

it's work

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ashish-algorythma picture ashish-algorythma  路  7Comments

rajeshkos picture rajeshkos  路  6Comments

kalyanijamunkar10 picture kalyanijamunkar10  路  5Comments

roadev picture roadev  路  3Comments

IvanCaceres picture IvanCaceres  路  6Comments