react-nativepdfexpobase64expo-file-system

Save base64 PDF to cache directory, and open it with system's default PDF reader


I have a base64 PDF string, and need to save it to a file, to open it on the system (android or ios), I wanted it to be on cache's directory because it's a one-time view only in most cases.

But expo (or maybe android) is giving me and error about "intent" when I try to open the file with linking

I'm using expo btw

The error message i'm getting is: [Error: Could not open URL 'file:///data/user/0/host.exp.exponent/cache/Despacho%20-%2000043651620108260142.pdf': file:///data/user/0/host.exp.exponent/cache/Despacho%20-%2000043651620108260142.pdf exposed beyond app through Intent.getData()]

I'm using this function to save and open the file, but nothing happens except for the error I'm getting:

async function saveAndOpenFile(fileName: string, content: string) {
    try {
        let directoryUri = FileSystem.cacheDirectory + fileName;
        console.log("D", directoryUri);

        const writed = await FileSystem.writeAsStringAsync(directoryUri, content, { encoding: FileSystem.EncodingType.Base64 });
        console.log("W", writed);

        await Linking.openURL(directoryUri);
    } catch (error) {
        Alert.alert("Ocorreu um erro", "Não foi possível abrir o documento");
        console.log(error);
    }
}

My console output is:

 LOG  D file:///data/user/0/host.exp.exponent/cache/Despacho%20-%2000043651620108260142.pdf
 LOG  W null
 LOG  [Error: Could not open URL 'file:///data/user/0/host.exp.exponent/cache/Despacho%20-%2000043651620108260142.pdf': file:///data/user/0/host.exp.exponent/cache/Despacho%20-%2000043651620108260142.pdf exposed beyond app through Intent.getData()]

Solution

  • I found a solution by doing this:

    const [viewUri, setViewUri] = React.useState<string | null>(null);
    
    async function saveAndOpenFile(fileName: string, content: string) {
        try {
            let fileUri = FileSystem.documentDirectory + fileName;
            await FileSystem.writeAsStringAsync(fileUri, content, { encoding: FileSystem.EncodingType.Base64 });
    
            const cUri = await FileSystem.getContentUriAsync(fileUri);
    
            if (Platform.OS === "android") {
                await IntentLauncher.startActivityAsync("android.intent.action.VIEW", {
                    data: cUri,
                    flags: 1,
                    type: "application/pdf",
                });
    
                console.log("CLOSING NOW");
                closeModal();
            } else {
                setViewUri(cUri); // Set as variable to display a webview below
            }
        } catch (error) {
            Alert.alert("Ocorreu um erro", "Não foi possível abrir o documento");
            console.log(error);
        }
    }
    
    return (
        <WebView
            allowFileAccess
            allowFileAccessFromFileURLs
            allowUniversalAccessFromFileURLs
            scalesPageToFit
            mixedContentMode={Platform.OS === "android" ? "always" : undefined}
            sharedCookiesEnabled={false}
            originWhitelist={["http://*", "https://*", "file://*", "data:*", "content:*"]}
            style={{
                flex: 1,
            }}
            scrollEnabled={true}
            source={{ uri: viewUri }}
            bounces={false}
        />;
    
    )