Not sure i can show a reproducible example as this problem only seems to happen when creating an APK through expos build process.
This is my first time making an issue, please let me know if you need anymore information.
I get "location isn't readable" when i try to use FileSystem.readAsStringAsync on an image uri, to encode it with base64. But only in a built apk, in dev it works fine.
I am trying to show an image, from the projects assets folder, in html with the code shown below, using FileSystem.readAsStringAsync to encode it with base64.
const androidDrawableResPath = `file:///android_res/drawable`;
const getAndroidReleaseImageURI = (sourceURI: string) =>
`${androidDrawableResPath}/${sourceURI}`;
const getLogoUri = async () => {
const image = Image.resolveAssetSource(require('../../../assets/logo.png'));
const data = await FileSystem.readAsStringAsync(
getAndroidReleaseImageURI(image.uri),
encoding: FileSystem.EncodingType.Base64,
return 'data:image/png;base64,' + data
const logoUri = getLogoUri()
<img src="${logoUri}" />
Now that works just fine when running dev, but not in a built apk. In the built apk, i get the "location isn't readable" error on FileSystem.readAsStringAsync.
I use the workaround found here: facebook/react-native#18216 because i would get an "unsupposeted scheme" error when trying to use Asset.loadAsync to get the image uri.
Environment
expo-env-info 1.0.5 environment info:
System:
OS: Windows 10 10.0.19044
Binaries:
Node: 16.13.0 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.18 - ~\AppData\Roaming\npm\yarn.CMD
npm: 8.1.0 - C:\Program Files\nodejs\npm.CMD
IDEs:
Android Studio: AI-221.6008.13.2211.9619390
npmPackages:
@expo/webpack-config: ^18.0.1 => 18.1.0
expo: ^48.0.19 => 48.0.19
react: 18.2.0 => 18.2.0
react-dom: 18.2.0 => 18.2.0
react-native: 0.71.8 => 0.71.8
react-native-web: ~0.18.10 => 0.18.12
Expo Workflow: managed
I have the same issue but only using Expo go on Android. On standalone builds is working as expected.
Could you share your code that runs in standalone builds? I'm curious to see if yours differ from mine in some significant fashion
I have the same issue but only using Expo go on Android. On standalone builds is working as expected.
Could you share your code that runs in standalone builds? I'm curious to see if yours differ from mine in some significant fashion
I have something like this this:
const result = await DocumentPicker.getDocumentAsync({
type: ["image/png" "image/jpg", "image/jpeg", "application/pdf"]
if (result.type === "success") {
const uri = result.uri
const encodedFile = await FileSystem.readAsStringAsync(uri, { encoding: EncodingType.Base64 })
setFile(encodedFile)
I have the same issue but only using Expo go on Android. On standalone builds is working as expected.
Could you share your code that runs in standalone builds? I'm curious to see if yours differ from mine in some significant fashion
I have something like this this:
const result = await DocumentPicker.getDocumentAsync({
type: ["image/png" "image/jpg", "image/jpeg", "application/pdf"]
if (result.type === "success") {
const uri = result.uri
const encodedFile = await FileSystem.readAsStringAsync(uri, { encoding: EncodingType.Base64 })
setFile(encodedFile)
Thanks. Its just so strange, i use FileSystem.readAsStringAsync in the exact same way, but with an image. And it doesn't work in a built apk. It just give me "assets_logo.png"
can someone in the thread please share a minimal reproducible example? you should be able to reproduce it in a built apk by running npx expo run:android --configuration release
. remove any unrelated code that isn't needed to reproduce, it should be just the blank template + minimal code
Thank you.
I created a reproducible example, but i had problems creating a apk with the exact method you described, so i created one through the expo build process, like i'm doing in my original project.
Snack: https://snack.expo.dev/@kasperandersen/no-img-apk-example
Project that you can install by opening on your device: https://expo.dev/accounts/kasperandersen/projects/no-img-apk-example/builds/f2444070-bf36-44c7-8474-d641e0d49ff0
The code in the snack isn't the exact same as my original post (sorry), but the root of the problem is the same. If i try to use any expo api to get an uri from an image, be it Asset.loadAsync, Image.resolveAssetSource (this one is RN, not expo) or whatever else, to dispaly in a pdf, it will work just fine in dev, but as soon as i create a built apk, the uri changes to something like "assets_nameOfImage".
Note that i alert the uri in the createPdf.js file, and it clearly shows the proper uri in dev, but just a weird string in the apk
In my original link: facebook/react-native#18216 someone talks about it being a problem with the metro bundler (comment is minimized).
Pictures of local dev and apk:
I was having a similar issue as well. Mine was failing in dev running in Expo Go on Android, but I haven't tried running a production build.
In my use case I am trying to load a PDF document form and programmatically fill it out and write it back into a user selected directory. To do that I select a pdf using DocumentPicker
and the directory with StorageAccessFramework
as follows.
const handleSelectPDF = async () => {
try {
const { uri: selectedCharacterSheet, name } =
await DocumentPicker.getDocumentAsync({
type: 'application/pdf'
});
setPdfFile({ uri: selectedCharacterSheet, name });
} catch (error) {
alert(error);
const handleSelectOutputFolder = async () => {
try {
const { directoryUri: selectedDirectory } =
await FileSystem.StorageAccessFramework.requestDirectoryPermissionsAsync();
if (selectedDirectory) {
setOutputPathUri(selectedDirectory);
return;
alert('Permissions for storage are required to use the export feature!');
} catch (error) {
console.error(error);
alert(error);
App is contanerised in Docker.
Host Machine
System:
OS: Ubuntu 22.04.2 (Jammy Jellyfish)
Shell: 5.0.3 - /bin/bash
Container in Docker
expo-env-info 1.0.5 environment info:
System:
OS: Linux 6.2 Debian GNU/Linux 10 (buster) 10 (buster)
Shell: GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)
Binaries:
Node: 16.20.1 - /usr/local/bin/node
Yarn: 1.22.19 - /usr/local/bin/yarn
npm: 8.19.4 - /usr/local/bin/npm
npmPackages:
babel-preset-expo: ^9.3.0 => 9.5.0
expo: ^48.0.0 => 48.0.20
react: 18.2.0 => 18.2.0
react-native: 0.71.8 => 0.71.8
Expo Workflow: managed
The only thing that got it working for me was by using the copyToCacheDirectory: false
option on the getDocumentAsync
. This however, is documented as not ideal if the user will be picking larger files which I assume would be a common issue when dealing with images.
I can try to get a standalone build of this app running and report back. If I face the same issue in a build then I can try to create a simple example project to replicate the issue.
hi all! Same problem at expo 48.
I had to set the copyToCacheDirectory flag to false in the DocumentPicker
and do this
if (Platform.OS === 'android' && uri.startsWith('content://')) {
// Create a temporary path to copy the file
const tmpFileURI = FileSystem.cacheDirectory! + new Date().getTime() + '.jpg';
// Copy the file from the content:// URI to a local directory
await FileSystem.copyAsync({
from: uri,
to: tmpFileURI,
uri = tmpFileURI;
const content = await FileSystem.readAsStringAsync(uri, { encoding: EncodingType.Base64 });
this is strange(
can someone in the thread please share a minimal reproducible example? you should be able to reproduce it in a built apk by running npx expo run:android --configuration release
. remove any unrelated code that isn't needed to reproduce, it should be just the blank template + minimal code
Thank you.
I created a reproducible example, but i had problems creating a apk with the exact method you described, so i created one through the expo build process, like i'm doing in my original project.
Snack: https://snack.expo.dev/@kasperandersen/no-img-apk-example Project that you can install by opening on your device: https://expo.dev/accounts/kasperandersen/projects/no-img-apk-example/builds/f2444070-bf36-44c7-8474-d641e0d49ff0
The code in the snack isn't the exact same as my original post (sorry), but the root of the problem is the same. If i try to use any expo api to get an uri from an image, be it Asset.loadAsync, Image.resolveAssetSource (this one is RN, not expo) or whatever else, to dispaly in a pdf, it will work just fine in dev, but as soon as i create a built apk, the uri changes to something like "assets_nameOfImage". Note that i alert the uri in the createPdf.js file, and it clearly shows the proper uri in dev, but just a weird string in the apk
@viking11
I had this issue where the code will work on ios and android locally, but when building android I get asset_name as local uri, going thro the code here ( https://github.com/expo/expo/blob/main/packages/expo-asset/src/PlatformUtils.ts#L93 ) I was able to transform it back to URI for readAsStringAsync
and it works 🚀
export async function readAssetFile({ file }: { file: any}) {
const [{ localUri, name, hash, type }] = await Asset.loadAsync(file);
let uri = localUri ?? '';
if (!uri?.startsWith('file://')) {
if (Platform.OS === 'android') {
uri = `${cacheDirectory}ExponentAsset-${hash}.${type}`;
return readAsStringAsync(uri, { encoding: 'base64' });
const imgRequire = require('./assets/test-image.png');
const imgBase64 = await readAssetFile({file: imgRequire});
Hope this solve your issue.
[SDK 51] [IOS] expo-file-system readAsStringAsync() is throwing 'File is not readable' error
#29058