Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error: 'Location...not readable' when using localUri from Asset.loadAsync for FileSystem.getInfoAsync or FileSystem.readAsStringAsync on Android

Attempting to load in a .txt asset as a string in Expo using Asset.loadAsync

Asset.loadAsync(module) resolves and provides a localUri

However, FileSystem.readAsStringAsync(localUri) throws an error: Location 'file:/data/user/0/host.exp.exponent/files/.expo-internal/deaba7963cc3ce7f03f36c3b210a771f.txt' isn't readable

THIS ONLY HAPPENS ON ANDROID. File loads fine on iOS.

Expected Behavior: File provided by Asset.loadAsync(module) is readable.

Example Expo Project Published Here

App.js

import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import Constants from 'expo-constants';
import * as FileSystem from 'expo-file-system'
import { Asset } from 'expo-asset'

export default function App() {
  const [message, setMessage] = React.useState("")

  React.useEffect(() => {
    (async () => {
      const [{localUri}] = await Asset.loadAsync(require('./assets/fff.txt'));
      try {
        const str = await FileSystem.readAsStringAsync(localUri);
        setMessage(str);
      } catch (e) {
        setMessage(e.message);
      }
    })()
  }, [])

  return (
    <View style={styles.container}>
      <Text>Message: { message }</Text>
    </View>
  );
}

const styles = ...

assets/fff.txt

This text is from fff.txt
Got it successfully!

metro.config.js

const { getDefaultConfig } = require('@expo/metro-config');

const defaultConfig = getDefaultConfig(__dirname);

module.exports = {
  resolver: {
    assetExts: [...defaultConfig.resolver.assetExts, 'txt'],
  },
};

package.json

{
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "eject": "expo eject"
  },
  "dependencies": {
    "@expo/metro-config": "^0.1.48",
    "expo": "~40.0.0",
    "expo-asset": "~8.2.1",
    "expo-constants": "~9.3.1",
    "expo-file-system": "~9.3.0",
    "expo-status-bar": "~1.0.3",
    "react": "16.13.1",
    "react-dom": "16.13.1",
    "react-native": "https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz",
    "react-native-paper": "3.6.0",
    "react-native-web": "~0.13.12"
  },
  "devDependencies": {
    "@babel/core": "~7.9.0"
  },
  "private": true
}

App.json

{
  "expo": {
    "name": "healthy-edamame",
    "slug": "snack-9f640e40-68ed-4cdc-92a6-37315a56d405",
    "version": "1.0.0",
    "orientation": "portrait",
    "icon": "./assets/icon.png",
    "splash": {
      "image": "./assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#ffffff"
    },
    "updates": {
      "fallbackToCacheTimeout": 0
    },
    "assetBundlePatterns": [
      "**/*"
    ],
    "ios": {
      "supportsTablet": true
    },
    "android": {
      "adaptiveIcon": {
        "foregroundImage": "./assets/adaptive-icon.png",
        "backgroundColor": "#FFFFFF"
      }
    },
    "web": {
      "favicon": "./assets/favicon.png"
    }
  }
}
like image 419
Sam Chen Avatar asked Jan 31 '26 05:01

Sam Chen


1 Answers

I got the same error and when I console log the localUri I got below output

/data/user/0/host.exp.exponent/cache/ExperienceData/72a2e181-7f07-480e-bf63-ddb4114958a6.jpeg

so what I did was I just passed the localUri in encode function and use the returned url as shown below

const encode = (uri) => {
  if (Platform.OS === 'android') return encodeURI(`file://${uri}`)
  else return uri
}
let newurl = encode(localUri);

you can also use below code to check if the uri path exists

 const fileInfo = await FileSystem.getInfoAsync(newurl);
 console.log(fileInfo) //Object{"exists": true,...}
like image 163
vivek sharma Avatar answered Feb 03 '26 11:02

vivek sharma



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!