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"
}
}
}
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,...}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With