MailComposer Attachments not working (android)

Continuing the discussion from MailComposer example:

When I attach some file uri to MailCompoer, gmail complains “Permission denied for the attachement”.
Outlook complains that “Unable to add attachment due ot IO error”.

Below are the methods in my react class component. Could you tell me what I am doing wrong?

writeHTML=()=>{
    FileSystem.writeAsStringAsync(`${FileSystem.documentDirectory}ePPMC/chart`, '<html>Hello</html>').then(result=>{
      FileSystem.readAsStringAsync(`${FileSystem.documentDirectory}ePPMC/chart`).then(result=>{
        console.log("readAsStringAsync response data>>>", result)
      })
      
    })
    
}

openEmail=()=>{
    MailComposer.composeAsync({
      recipient:"",
      subject:"Sending you the chart",
      body:"Hi, please find attached the chart.",
      attachments: [`${FileSystem.documentDirectory}ePPMC`]
    })
}

Thank you.

can you inspect the raw email in either of those mail clients? there may be some information in the raw email you receive.

Or do you mean you get this error before even sending?

Hi, ccheever

Thank you for your reply.
Yes, I get this error as soon as I execute MailComposer.composeAsync - before even sending.
It displays a selection of my email applications, and when I select gmail for example, it opens gmail compose, with the title and body, but no attachment and shows the error.

can you try to use the FileSystem API or similar to inspect the contents of the files at those URLs that you are trying to attach? I think the most likely thing is that you’re not grabbing a real file to attach.

Hi, cchever

I am using expo’s FileSystem.
I made a quick demo of my issue below.
github repo

expo demo

I just tried with iphone as well. It throws a better error.
It says nil argument, which suggests that I am not attaching the file correctly as you said?

Exception '*** -[NSPlaceholderString initWithString:]: nil argument' was thrown while invoking composeAsync on target ExponentMailComposer with params (....

But, how can I attach my file which I wrote to asyncStorage and I can see that the file is written there via console.log.

Your help is highly appreciated.

@aalices - could you chime in here? Is this possible or do we need to get a content:// uri somehow?

Hello @nfabacus sorry for the error! I used your snack and appended .html to file name and managed to attach the file. Let me know if this helps you :slight_smile:

2 Likes

HI @aalices

I tried with .html previously and again just now. Still no luck…

componentDidMount() {
    FileSystem.makeDirectoryAsync(FileSystem.documentDirectory + `myattachments`).catch(e => {
      console.log(e, 'Directory exists');
    });
  }

  writeHTML=()=>{
    FileSystem.writeAsStringAsync(`${FileSystem.documentDirectory}myattachments/myhtml.html`, "<html>Hello</html>").then(result=>{
      FileSystem.readAsStringAsync(`${FileSystem.documentDirectory}myattachments/myhtml.html`).then(result2=>{
        console.log("readAsStringAsync response data >>", result2)
      })
      
    })
    
  }

  openEmail=()=>{
    MailComposer.composeAsync({
      recipient:"",
      subject:"attachment is not working",
      body:"Hi! Here is the attachment...",
      attachments: [`${FileSystem.documentDirectory}myattachments/myhtml.html`]
    })
  }

Is the above what you mean?
not working for me…
I am using android v7.0 Samsung s7

Is there any permission setting I need to ask users first?

Thank you for your help.

@aalices and others

After some attempts, I managed to attach an html file to email with an iPhone - previously did not work but finally worked somehow.

However, it is still not working with my android phone. I have a bad feeling that MailComposer attachment will not work with Android… Please tell me if I am wrong.

I also looked at Share, but I cannot attach anything programmatically.

The only options left for me:
A. detach my app from expo to ExpoKit. - I tried this but so far no luck.
If I can detach my app and still make it work with some email library by linking…

B. If detach and link do not work either, then I have to rebuild my app with pure react native from scratch so that I can install some email library… However, It will be shame to give up expo all together…I have spent last few months building an app with Expo…

Hi! I think I found the reason why you cannot add your file as an attachment on Android and I’ll try to find a way to fix it. It is caused by adding a file that is in documentDirectory and not cacheDirectory - if you move your file there and use the uri of the moved file it should work just fine. Of course, files in document directory should also work - I hope to fix this soon!

1 Like

@aalices Thank you so much! cacheDirectory works! It is a nice surprise!
A couple of days ago I read that asyncStorage saves data specific to each app, and not accessible from other apps. So, I thought that is why email apps cannot attach (find) files from asyncStorage.

Do you still think that files in documentDirectory should also work in theory? The thing is I prefer the fact that the confidential data is not easily accessible from outside the app, but still wanting to attach a file/data from asyncStorage to an email.

Anyway, I updated my repo and snack just in case anybody else come across the same thing as me. (I will also test if I can attach an html with some image blob).

Kind regards,
Noby

Good point. Files saved by Expo’s File System aren’t accessible for other apps by default. It requires some configuration to be able to share something with an external app. We only use this possibility for MailComposer. So, even if we let users to use documentDirectory as a root dir for files they want to share via an email, the files will still be unavailable for other apps :slight_smile:

1 Like

excellent. Thank you.

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.