I have to generate a CSV file, pluck it from local storage, upload it to AWS, then mail the link to the user for access.
iOS is generating the CSV, uploading successfully, and emailing correctly, while Android is not.
I have tried every combination I can think of to get the file from local storage/scoured multiple forums and stackoverflow posts, changes the write directories, but nothing comes close to answering my questions.
The file permissions are set correctly with Read/Write External Storage, I have a prompt to ensure that the user accepts the terms of access, and have tested to make sure the directory is working properly.
For this particular app, we are using React Native v 0.57
Code is split between two functions:
async function requestFileStoragePermission() {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
{
'title': 'External Storage',
'message': 'This app needs permission to save csv files to your device.'
}
)
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log("You can save files")
} else {
console.log("Save files permission denied")
}
} catch (err) {
console.warn(err)
}
}
async function requestFileReadingPermission() {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE,
{
'title': 'Read csv Files',
'message': 'This app needs permission to read csv files from your device.'
}
)
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log("You can read files")
} else {
console.log("Read files permission denied")
}
} catch (err) {
console.warn(err)
}
}
if(Platform.OS === 'android') {
requestFileStoragePermission()
requestFileReadingPermission()
}
// write the current list of answers to a local csv file
const pathToWrite = `${RNFetchBlob.fs.dirs.DocumentDir}/Employee_Timesheet1.csv`;
RNFetchBlob.fs
.writeFile(pathToWrite, csvString, 'utf8')
.then(() => {
console.log('Upload phase')
fileLink = uploadCSV(pathToWrite, 'Employee_Timesheet1.csv');
return fileLink;
})
.then((res) => {
Mailer.mail({
subject: `Timesheet for ${employeeName}`,
recipients: ['my@email.com'],
ccRecipients: [],
bccRecipients: [],
body: `<b>Employee Timesheet for ${employeeName}</b>/n<b>Click here to download ${res}</b>`,
isHTML: true
}, (error, event) => {
console.log(error, event);
Alert.alert(
error,
event,
[
{ text: 'Ok', onPress: () => console.log('OK: Email Error Response') },
{ text: 'Cancel', onPress: () => console.log('CANCEL: Email Error Response') }
],
{ cancelable: true }
)
});
})
.catch(error => console.error(error));
}
//And then there's a function that handles uploading to AWS:
export function uploadCSV(csvPath, fileName) {
let type = 'text/csv'
const fileInformation = {
uri: csvPath,
name: fileName,
type: type
}
//Options omitted due to sensitive information.
let fileLink = RNS3.put(fileInformation, options)
.then(response => {
if (response.status !== 201) {
throw new Error(response.status, response.status);
} else {
return response.body.postResponse.location;
}
})
return fileLink;
}
When I run the following code, I get the following error:
status: 0
text: "Could not retrieve file for uri /data/user/0/com.app/files/Employee_Timesheet1.csv"
const fileInformation = {uri : ${Platform.OS === 'android' ? 'file://' : ''}${csvPath}, name : fileName, type : type}