skip to Main Content

I have a use-case in my react native app wherein I have to load and display a pdf from an endpoint and also share the same as an attachment(to Gmail app or WhatsApp or even download it) using the native share options (both ios and Android).

I’m currently using the react-native-pdf library to load and show the pdf on the app and it’s working fine. The problem is with the share option. I tried using facebook’s Share API to achieve this but unfortunately, it doesn’t serve my purpose as the pdf file is shared as a link and in Android, I had to pass both message and pdfUrl the same value (at least to get the same result across platforms). I want the pdf file to be shared as an attachment when clicked on any of the share options.

below is my code for the same:

class ViewPdfScreen extends Component<Props, {}> {
  render() {

    const pdfUrl = 'http://samples.leanpub.com/thereactnativebook-sample.pdf'

    const source = {
      uri: pdfUrl,
      cache: true,
      expiration: 900, // cache file expired seconds (0 is not expired)
    };

    return (
      <View style={styles.container}>
        <View style={styles.subContainer}>
          <Text>{title}</Text>
          <TouchableOpacity onPress={() => this.sharePdf(title, pdfUrl)}>
            <Image source={shareBtn} />
          </TouchableOpacity>
        </View>
        <View style={styles.pdfContainer}>
          <Pdf
            source={source}
            onLoadComplete={(numberOfPages, filePath) => {
              console.log(`number of pages: ${numberOfPages}`);
            }}
            onPageChanged={(page, numberOfPages) => {
              console.log(`current page: ${page}`);
            }}
            onError={error => {
              console.log(error);
            }}
            onPressLink={uri => {
              console.log(`Link presse: ${uri}`);
            }}
            style={styles.pdf}
          />
        </View>
      </View>
    );
  }

  shareBill = (title: string, billUrl: string) => {
    Share.share(
      {
        message: billUrl,
        url: billUrl,
        title: title,
      },
      {
        // Android only:
        dialogTitle: `Share ${title}`,
        // iOS only:
        excludedActivityTypes: ['com.apple.UIKit.activity.PostToTwitter'],
      },
    )
      .then(res => console.log(res))
      .catch(error => console.log(error));
  };
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  subContainer: {
    elevation: 4,
    height: 100,
    flexDirection: 'row',
    backgroundColor: colors.orange,
    justifyContent: 'space-between',
    alignItems: 'flex-end',
    padding: 16,
  },
  pdfContainer: {
    flex: 1,
  },
  pdf: {
    flex: 1,
    width: Dimensions.get('window').width,
    height: Dimensions.get('window').height,
  },
});

export default connect()(ViewPdfScreen);

Did anyone came across a similar situation or have any solution for this?

want something similar to this below (taken from google)

enter image description here

2

Answers


  1. Chosen as BEST ANSWER

    I've managed to solve this question using the react-native-share library. But unfortunately, this has a problem sharing on Android and throwing an error Cannot attach the file.

    Sharing the answer here as I cannot post the entire code in the comments section.

    shareBill = async (title: string) => {
        const billPdfPath = this.props.billPdfDataFetched?.path;
    
        if (!billPdfPath) {
          return;
        }
    
        const newPath = `${RNFetchBlob.fs.dirs.CacheDir}/${title}_bill.pdf`;
    
        await RNFetchBlob.fs.cp(billPdfPath, newPath);
    
        const shareOptions = {
          title: title,
          subject: `${strings('emailSubject')} – ${title}`,
          message: `${title} bill`,
          url: `file://${newPath}`,
          type: 'application/pdf',
          failOnCancel: true,
        };
    
        try {
          await RNShare.open(shareOptions);
        } catch (err) {
          // do something here
        } finally {
          RNFetchBlob.fs.unlink(newPath);
        }
      };
    

    Permissions on AndroidManifest file

    <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission tools:node="remove" android:name="android.permission.READ_PHONE_STATE" />
        <uses-permission tools:node="remove" android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission tools:node="remove" android:name="android.permission.READ_EXTERNAL_STORAGE" />
    

    If anyone else has faced a similar problem sharing it with Android, please do help me.


  2. react-native-file-share is a library which provides this functionality.

    Or

    https://github.com/react-native-community/react-native-share
    You can try react-native-share as well.

    Share file directly
    
    When share a local file directly, please follow the format below:
    
    url: "file://<file_path>",
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search