I am currently working on a react-native project where the user can upload a video from his app to firebase storage.
The user can either select a video from his library or take a new one directly in the app. I use the react-native-image-picker
library.
On IOs everything is working as expected. On Android I only managed to upload videos taken directly in the app or small videos from the android gallery.
If I try to upload videos from the android gallery I encounter two problems:
- Error: [storage/unknown] Permission Denial: reading com.android.providers.media.MediaDocumentsProvider uri content://com.android.providers.media.documents/document/video:723 from pid=32673, uid=10226 requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs
This Error occurs if try to upload the video directly with the link I get from the image picker library.
let reference = storage().ref(path);
let task = reference.putFile(imagePickerResponse.assets[0].uri);
I managed to resolve this issue by using the RNFS library. react-native-fs
const data = await RNFS.readFile(imagePickerResponse.assets[0].uri, 'base64');
let task = reference.putString(data, 'base64');
But this solution only works for small files. For longer videos the app crashs and I get the following error.
- Could not invoke RNFSManager.readFile:
Could not invoke RNFSManager.readFile
null
Failed to allocate a 268435472 byte allocation with
6291456 free bytes and 116MB until OOM, target
footprint 152234472, growth limit 268435456
Unfortunately I couldnt find any solution online. Is there any way to upload large video from the Android library to firestore storage?
Image Picker Code
export const SelectVideoAction: CameraAction = {
title: 'Select Video',
type: 'library',
options: {
selectionLimit: 0,
mediaType: 'video',
},
};
launchImageLibrary(SelectVideoAction.options, handleResponse);
Android Upload Code
let reference = storage().ref(targetPath);
let task = reference.putFile(imagePickerResponse.assets[0].uri);
if (Platform.OS === 'android' && fromLibrary) {
const data = await RNFS.readFile(imagePickerResponse.assets[0].uri, 'base64');
task = reference.putString(data, 'base64');
}
task
.then(() => {
console.log('Image uploaded to the bucket!');
})
.catch((e) => console.log('uploading image error => ', e));
Dependencies
"dependencies": {
...
"react": "17.0.2",
"react-native": "0.66.3",
"react-native-image-picker": "^4.0.6",
"react-native-fs": "^2.18.0",
...
}