react-native-mail
react-native-mail copied to clipboard
Can't attach the file in email for the android mobile.
I'm using the below code. It's working fine in the IOS mobile. But Not working in the Android mobile. An error shows the "permission denied for the attachment". After I'm change the path path:'file://'+DocumentDirectoryPath + '/Log.txt', That time an error shows the "can't attach the empty file" `sendMail = (issueType) => {
Mailer.mail({
subject: 'need help',
recipients: ['[email protected]'],
ccRecipients: ['[email protected]'],
bccRecipients: ['[email protected]'],
body: '<b>A Bold Body</b>',
isHTML: true,
attachment: {
path: DocumentDirectoryPath + '/Log.txt', // The absolute path of the file from which to read data.
type: 'text', // Mime Type: jpg, png, doc, ppt, html, pdf, csv"Fetchh_Log.txt"
name: 'Log.txt', // Optional: Custom filename for attachment
}
}, (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 }
)
});
}`
Any mistake in the above code? or any changes for android mobile?
Hi I am currently facing this issue as well. Please help.
For anyone still struggling with this issue, it is no longer recommended to share data such as an attachment using the file:// scheme. The solution is to implement a FileProvider. It allows you to securely pass file defined through an intent.
Useful links
https://inthecheesefactory.com/blog/how-to-share-access-to-file-with-fileprovider-on-android-nougat/en https://stackoverflow.com/questions/18249007/how-to-use-support-fileprovider-for-sharing-content-to-other-apps
Hope this helps
+1
It's working fine in the iOS mobile. But not working in the Android Mobile.
Hope this helps someone.
I had an issue attaching an image. Gmail would error with "unable to attach".
As I was using react-native-image-picker get the image, it was being returned via a content provider. The path would start content:/.
Creating a file from that path wasn't working. If you create a Uri directly from the path that was passed in, it worked.
ReadableMap attachment = options.getMap("attachment");
if (attachment.hasKey("path") && !attachment.isNull("path")) {
String path = attachment.getString("path");
Uri p = Uri.parse(path);
i.putExtra(Intent.EXTRA_STREAM, p);
}
}
You must save the image to device's picture directory.
import RNFS from "react-native-fs";
var destPath = RNFS.PicturesDirectoryPath + '/yourpicture.jpg'; RNFS.moveFile(data.uri, destPath) .then((success) => { console.log('file moved!'); }) .catch((err) => { console.log("Error: " + err.message); });
//then in your Mailer.mail attachment //the correct path should be /storage/emulated/0/Pictures/yourpicture.jpg
path: destPath
You must save the image to device's picture directory.
import RNFS from "react-native-fs";
var destPath = RNFS.PicturesDirectoryPath + '/yourpicture.jpg'; RNFS.moveFile(data.uri, destPath) .then((success) => { console.log('file moved!'); }) .catch((err) => { console.log("Error: " + err.message); });
//then in your Mailer.mail attachment //the correct path should be /storage/emulated/0/Pictures/yourpicture.jpg
path: destPath
still has the error with "can not attach empty file." The source uri(data.uri) I am using was "file:///data/user/0/com.myapp/cache/mypicture.jpg", and the desPath is exactly what you mentioned. The moveFile function seems not work either. Could you help check? Thanks!
You must save the image to device's picture directory. import RNFS from "react-native-fs"; var destPath = RNFS.PicturesDirectoryPath + '/yourpicture.jpg'; RNFS.moveFile(data.uri, destPath) .then((success) => { console.log('file moved!'); }) .catch((err) => { console.log("Error: " + err.message); }); //then in your Mailer.mail attachment //the correct path should be /storage/emulated/0/Pictures/yourpicture.jpg path: destPath
still has the error with "can not attach empty file." The source uri(data.uri) I am using was "file:///data/user/0/com.myapp/cache/mypicture.jpg", and the desPath is exactly what you mentioned. The moveFile function seems not work either. Could you help check? Thanks!
Have you check after you move the file does it success?
You must save the image to device's picture directory. import RNFS from "react-native-fs"; var destPath = RNFS.PicturesDirectoryPath + '/yourpicture.jpg'; RNFS.moveFile(data.uri, destPath) .then((success) => { console.log('file moved!'); }) .catch((err) => { console.log("Error: " + err.message); }); //then in your Mailer.mail attachment //the correct path should be /storage/emulated/0/Pictures/yourpicture.jpg path: destPath
still has the error with "can not attach empty file." The source uri(data.uri) I am using was "file:///data/user/0/com.myapp/cache/mypicture.jpg", and the desPath is exactly what you mentioned. The moveFile function seems not work either. Could you help check? Thanks!
Uploading from cache folder wont work. You must move the file to picture directory. var destPath = RNFS.PicturesDirectoryPath + '/yourpicture.jpg';
I saw from PR 127 that after API Level 24, the exception will throw when an application exposes a file:// Uri to another app, and apps should use content:// Uris so the platform can extend temporary permission for the receiving app to access the resource.
https://developer.android.com/reference/android/os/FileUriExposedException
What is the absolute path for RNFS.PicturesDirectoryPath? It seems a relative path.
I have made a demo to send mail with photo as attachment.
https://github.com/azizimusa/react-native-mail-demo
I have made a demo to send mail with photo as attachment.
https://github.com/azizimusa/react-native-mail-demo
Thank you so much for your answers! I will learn your demo code. May I ask which level of the SDK API in your device?
Tested on Xiaomi MI5 Android 8.0 SDK 26
I have a workaround. You need to use react-native-fs
. The solution is to copy the file from the private app cache to the external storage which is readable by other apps.
let path = pdfFilePath;
if (Platform.OS !== 'ios') {
try {
let hasPermission = await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE);
if (!hasPermission) {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
{
title: i18n.t('write_storage_permission'),
message: i18n.t('write_storage_permission_message'),
buttonNegative: i18n.t('cancel'),
buttonPositive: i18n.t('ok'),
},
);
hasPermission = granted !== PermissionsAndroid.RESULTS.GRANTED;
}
if (!hasPermission) {
handleError(i18n.t('error_accessing_storage'));
return;
}
} catch (error) {
console.warn(error);
}
path = `${RNFS.ExternalStorageDirectoryPath}/project_overview_${Number(new Date())}.pdf`;
try {
await RNFS.copyFile(pdfFilePath, path);
} catch(error) {
handleError(get(error, 'message', error));
return;
}
}
function handleError(error) {
if (error === 'not_available') error = i18n.t('mail_not_available');
Alert.alert(
i18n.t('error'),
error,
[
{ text: i18n.t('ok') },
],
{ cancelable: true }
)
}
Mailer.mail({
subject: i18n.t('FinancingPlanning.loan_request_email_subject'),
recipients: [],
body: i18n.t('FinancingPlanning.loan_request_email_body', { name: get(user, 'profile.name', '') }),
isHTML: true,
attachment: {
path, // The absolute path of the file from which to read data.
type: 'pdf', // Mime Type: jpg, png, doc, ppt, html, pdf, csv
name: 'project_overview.pdf', // Optional: Custom filename for attachment
}
}, (error, event) => {
if (error) {
handleError(error);
}
});
In case anyone is still looking for a solution, that's what finally worked in my case: https://github.com/marcinolek/react-native-mail/commit/384d3629d2fe23bc1ded25447cad3532f515030b
Inspired by PR 127 & https://stackoverflow.com/questions/18249007/how-to-use-support-fileprovider-for-sharing-content-to-other-apps
@marcinolek Your fork works beautifully, thank you!
Should really consider adding this to this repo.
I had similar issue with attaching json file to mail. It just didn't appear in mail after sendMail func performed My solution was wrapping attachment file into array.
attachments: [{
path: '', // The absolute path of the file from which to read data.
type: '', // Mime Type: jpg, png, doc, ppt, html, pdf, csv
// mimeType - use only if you want to use custom type
name: '', // Optional: Custom filename for attachment
}]
RN: 0.63 React: 16.9 react-native-mail: 6.0.0
And of course our team used RNFS for getting an absolute path
You must save the image to device's picture directory.
import RNFS from "react-native-fs";
var destPath = RNFS.PicturesDirectoryPath + '/yourpicture.jpg'; RNFS.moveFile(data.uri, destPath) .then((success) => { console.log('file moved!'); }) .catch((err) => { console.log("Error: " + err.message); });
//then in your Mailer.mail attachment //the correct path should be /storage/emulated/0/Pictures/yourpicture.jpg
path: destPath
worked like a charm, thanks @azizimusa