I have been trying to get this to work for ages and have tried many different ways to get this to work. I am trying to get a bundled asset in an android app, created with expo 50, base64 encode it so I can use it to create a PDF. It works fine in development but after building the APK it doesn’t load. I am not able to use Asset from expo assets as that is for sdk 51 I believe. I have found threads elsewhere that say to prepend file:/// or file:///android_asset or file:///android_res to the resource identifier that is available from assets[0].localUri but none of these variations work, the issue is not that assets[0].localUri is undefined, it is that I don’t know how to use this resource identifier to access the resource with FileSystem. I have tried unzipping an APK to look at the file structure but it is not like a normal android app, I can’t see any mention of any of the image i am trying to use, however there are other images the app uses, for splash screen etc. and i cant find those either even though they do work. Here is a minimal version of the screen that I am trying to get working. I am greatful for any help.
import { View, Text, StyleSheet, Alert, Button } from 'react-native';
import { useAssets } from 'expo-asset';
import * as FileSystem from 'expo-file-system';
import RNHTMLtoPDF from 'react-native-html-to-pdf';
const App = () => {
const [assets, error] = useAssets([require('./assets/images/your-image.png')]);
const [base64Image, setBase64Image] = useState(null);
useEffect(() => {
const loadBase64Image = async () => {
if (assets && assets[0]) {
try {
const asset = assets[0];
const uri = asset.localUri || asset.uri;
if (!uri) {
Alert.alert("Error", "Asset URI is not available.");
return;
}
const base64 = await FileSystem.readAsStringAsync(uri, {
encoding: FileSystem.EncodingType.Base64,
});
setBase64Image(base64);
} catch (e) {
Alert.alert("Error", `Exception in loadBase64Image: ${e.message}`);
}
}
};
loadBase64Image();
}, [assets]);
const generatePDF = async () => {
if (!base64Image) {
Alert.alert("Error", "Base64 image data is not available.");
return;
}
const htmlContent = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PDF Document</title>
</head>
<body>
<h1>Base64 Image PDF Example</h1>
<img src="data:image/png;base64,${base64Image}" alt="Image" />
</body>
</html>
`;
const options = {
html: htmlContent,
fileName: 'test',
directory: 'Documents',
};
try {
const file = await RNHTMLtoPDF.convert(options);
Alert.alert('PDF Generated', `PDF saved to ${file.filePath}`);
} catch (e) {
Alert.alert("Error", `Failed to generate PDF: ${e.message}`);
}
};
return (
<View style={styles.container}>
<Text>Base64 Image PDF Example</Text>
<Button title="Generate PDF" onPress={generatePDF} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
},
});
export default App;