react-native-mail: 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: ['support@example.com'],
        ccRecipients: ['supportCC@example.com'],
        bccRecipients: ['supportBCC@example.com'],
        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?

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 5
  • Comments: 18

Most upvoted comments

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);
      }
    });

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

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

+1

It’s working fine in the iOS mobile. But not working in the Android Mobile.