0

There is the following problem in my React Native app. The app stored some PDF files as files and was able to access them. Then probably after recompilation the app started having problems accessing those files. However, the files are still there. I downloaded the app's full data container to check.

data container of the app

I have a suspicion it is because there is a dynamic part of the app's data container URI that always changes after recompilation followed by the actual path? e.g. D22506C1-9364-43A4-B3C7-F9FFF0E1CC48, 6BDC3F93-6BC3-4BB6-BD3F-9BFA7E4A4627

If so, what is the best practice to store URIs in React Native in database so they can be retrieved again?

The following 6 PDF files:

ListViewItem.js:30 Debug: Report URI /var/mobile/Containers/Data/Application/D22506C1-9364-43A4-B3C7-F9FFF0E1CC48/Documents/Reports/dk79lqddh3mlkcstqel9.pdf
ListViewItem.js:30 Debug: Report URI /var/mobile/Containers/Data/Application/D22506C1-9364-43A4-B3C7-F9FFF0E1CC48/Documents/Reports/e1exw1qg4cs6czktrfkfvi.pdf
ListViewItem.js:30 Debug: Report URI /var/mobile/Containers/Data/Application/D22506C1-9364-43A4-B3C7-F9FFF0E1CC48/Documents/Reports/zfy6hp3zf42me5ru32jfa.pdf
ListViewItem.js:30 Debug: Report URI /var/mobile/Containers/Data/Application/D22506C1-9364-43A4-B3C7-F9FFF0E1CC48/Documents/Reports/fum4qf23mwnzcmye39xau.pdf
ListViewItem.js:30 Debug: Report URI /var/mobile/Containers/Data/Application/D22506C1-9364-43A4-B3C7-F9FFF0E1CC48/Documents/Reports/btksznt1lxv7k4ey23bw93.pdf
ListViewItem.js:30 Debug: Report URI /var/mobile/Containers/Data/Application/6BDC3F93-6BC3-4BB6-BD3F-9BFA7E4A4627/Documents/Reports/smpkiggii4v7xmfhpnmdi.pdf

URIs as those can't be loaded at different places of the app:

Example 1

<Pdf style={styles.image} source={{ uri: 'file://' + this.props.pdf }} />

Example 2

FileService.readFileFromStorage('file://' + this.report.report_uri, 'base64')    

static readFileFromStorage(path, encoding) {
    return new Promise((resolve, reject) => {
        RNFS.readFile(path, encoding)
            .then((file) => {
                resolve(file);
            })
            .catch((err) => {
                console.log('Error: unable to read file', path, err.message);
                reject(err)
            });
    })

}

This was used to write the files:

FileService.writeFiletoStorage(r.taskId, 'pdf', base64Str)

static writeFiletoStorage(fileName, extention, base64Str) {
    return new Promise((resolve, reject) => {
        RNFS.mkdir(RNFS.DocumentDirectoryPath + '/Reports')
        var path = RNFS.DocumentDirectoryPath + '/Reports/' + fileName + '.' + extention;

        return RNFS.writeFile(path, base64Str, 'base64')
            .then((success) => {
                console.log('FILE WRITTEN!', path, success);
                resolve(path);
            })
            .catch((err) => {
                console.log('Error: unable to write file to storage', path, err.message);
                reject(err)
            });
    })

}
Peter G.
  • 6,748
  • 14
  • 67
  • 134

1 Answers1

1

The method to write file was returning the full path, which varies across different compilations. Returning just the relative path works better:

static writeFiletoStorage(fileName, extension, base64Str) {
        return new Promise((resolve, reject) => {
            RNFS.mkdir(RNFS.DocumentDirectoryPath + 'Reports')
            let path = '/Reports/' + fileName + '.' + extension;
            let fullPath = RNFS.DocumentDirectoryPath + path;

            return RNFS.writeFile(fullPath, base64Str, 'base64')
                .then((success) => {
                    console.log('FILE WRITTEN!', fullPath, success);
                    resolve(path);
                })
                .catch((err) => {
                    console.log('Error: unable to write file to storage', fullPath, err.message);
                    reject(err)
                });
        })

    }

Same change had to be made for method to read file:

static readFileFromStorage(path, encoding) {
    return new Promise((resolve, reject) => {
        let fullPath = RNFS.DocumentDirectoryPath + path;
        RNFS.readFile(fullPath, encoding)
            .then((file) => {
                resolve(file);
            })
            .catch((err) => {
                console.log('Error: unable to read file', fullPath, err.message);
                reject(err)
            });
    })

}
Peter G.
  • 6,748
  • 14
  • 67
  • 134
  • I am having the same issue, but isn't it `RNFS.DocumentDirectoryPath` that gives the dynamic path? – mXX Jun 22 '20 at 09:26