Convert content:// uri to file:// uri using react native

Viewed 4221

I'm currently trying to open a file using expo's FileSystem after getting the path from expo's DocumentPicker, but I can't find a way to make the URI from DocumentPicker readable to FileSystem. Everything works fine, I've no problems with permissions or anything else, but every tutorial I could find so far are basically for react native projects with exposed native code or Java.

Here I call DocumentPicker:

import * as DocumentPicker from 'expo-document-picker';

const Hello = ({navigation}) => (
  <HelloView>
    <HelloButton
      style={{
        backgroundColor: WhatsappStyles.colors.lightGreen,
      }}
      activeOpacity={0.5}
      onPress={() => {
        DocumentPicker.getDocumentAsync({
          copyToCacheDirectory: false,
        }).then(({uri}) => {
          navigation.navigate('LoadFile', {path: uri});
        });
      }
    }>
      <HelloButtonText>Go to App</HelloButtonText>
    </HelloButton>
  </HelloView>
);

And here I try (unsuccessfully) read the path:

import * as FileSystem from 'expo-file-system';


const LoadFile = ({navigation, route}) => {
  let [loading, setLoading] = useState(true);

  useEffect(() => {
    FileSystem.readAsStringAsync(route.params.path).then(result => {
    // do something here
    }
    setLoading(false);
  }, []);
...

I'm using react-navigation/stack for stack navigation and styled-components/native to build the components.

2 Answers

So, as far as I could find there's no way to "convert" content:// uri to file:// uri, but you can actually download the file to a cache or to the internal storage using FileSystem's downloadAsync function and use the file:// uri resulting from there.

e.g.

DocumentPicker.getDocumentAsync({
    copyToCacheDirectory: false,
}).then(({contentUri}) => {
    FileSystem.downloadAsync(
         contentUri, 
         FileSystem.documentDirectory + '<file name>')
    .then(({uri}) => {
         FileSystem.readAsStringAsync(uri)
         .then(result => {
              // do what you want here.
         });
    });
});
import * as ImagePicker from 'expo-image-picker'

let result = await ImagePicker.launchImageLibraryAsync({
    mediaTypes: ImagePicker.MediaTypeOptions.Images,
    allowsEditing: true,
    base64: true,
    aspect: [4, 3]
})

{ imageURL: result.uri, base64: result.base64 }

So, result.uri an image URL from FileSystem which you can use for displaying in Image and base64 send to yout store :)

Related