vinzscam/react-native-file-viewer

File paths with whitespaces breaks their extension and impedes visualization (Android 10)

Victorams opened this issue · 2 comments

The last couple of weeks my app had a problem that caused files to be opened with interrogation marks as if the extension was not recognized (even .JPEG`s or .JPG). Like this:

image

The files were downloaded (via RN-Fetch-Blob) but then could not be properly opened (via react-native-file-viewer). It happened in production, but only on some devices. Upon investigation, I discovered it to only happen on smartphones with Android 10 (maybe also Android 9? Did not test).

After a lot of pain in the ass, client complaints, and code reviewing (initially I thought the problem was with RN-Fetch-Blob), I discovered that the error was caused by simply having spaces on my file path:

const title = 'String with Spaces.png';
const directory = Platform.OS === 'android'
            ? RNFetchBlob.fs.dirs.DownloadDir
            : RNFetchBlob.fs.dirs.DocumentDir;
        const fullPath = `${directory}/${titulo}`;

        this.downloadRequest = await RNFetchBlob
        .config({ path: `${fullPath}` })
        .fetch('GET', url, {})
        .then((res) => {
            callback = () => this.readFile(res.path());
        });

If the variable "title" has no spaces, it works normally. I confirmed the problem is with react-native-file-viewer because the files are correctly downloaded on the device's storage (they can be accessed via the phone's Gallery).

I fixed it on my product by parsing my 'title' variable, but I think maybe it should also be fixed here since it certainly caused a lot of stress until I found out what was the problem. Maybe other people are also suffering it.

Anyway, thanks!

Same issue. Thank you for the insight!
I can confirm it also affected Android 9.

Android 11+ it works fine.

Side note: Emulators of any version are unable to reproduce the issue in my case.

workaround...

import {Platform} from 'react-native';
import DeviceInfo from 'react-native-device-info';

...
let dest = `${RNFS.DocumentDirectoryPath}/${name + '.' + extension}`;

if(Platform.OS === 'android') {
  let apiLevel = await DeviceInfo.getApiLevel();
  if(apiLevel <= 29) {
    let titleNoSpaces = name.replace(/\s/g, "-");

    dest = `${RNFS.DocumentDirectoryPath}/${titleNoSpaces + '.' + extension}`;
  }
}