2

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:

  1. 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.

  1. 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",
...
}
F.Fabian
  • 77
  • 10

1 Answers1

0

Main idea is to split the large video file into chunks, by this way it will not exceed the memory limit of the device and provide a more systematic upload process. Description for the solution sounds pretty good, but it can be very difficult to implement.

There is a package that can do chunk operation: React Native Chunk Upload. Does the default version of firebase storage allow chunk upload operations or this package compatible with firebase? I'm not sure but you can give it a try Uploading large files on web using Firebase. You have to change some configurations on firebase side and android permission, which is mentioned in documentation.

At the end of the day, you can consider using more suitable/powerful video storage/streaming service. (Google Cloud Storage (Multiple Chunk Upload), Cloudflare Stream, Mux)

I realize this isn't a complete answer, but I wanted to share it as it might help you or someone else.

EkremAy
  • 139
  • 6