React-native, how to get file-asset image absolute path?
So, the reason why you only get an url is because it image might not be stored on the device (it could be on iCloud). iOS silently downloads the asset for you once you do any operation on it.
That will not help you if you are really trying to manipulate the image from your react-native code though, so here is one workaround:
import RNFS from 'react-native-fs';
getAssetFileAbsolutePath = async (assetPath) => {
const dest = `${RNFS.TemporaryDirectoryPath}${Math.random().toString(36).substring(7)}.jpg`;
try {
let absolutePath = await RNFS.copyAssetsFileIOS(assetPath, dest, 0, 0);
} catch(err) {
// ...
}
}
Bare in mind this copies the file to a temporary directory which means it is not permanent, you can also copy it to your application's document directory.
How to get absolute path of a file located in the assets folder with react-native and expo?
Use Asset
module
import { Asset } from 'expo';
...
async render() {
const pdfURI = await Asset.fromModule(require('.assets/doc/wantedfile.pdf')).uri;
}
...
Check here for detail: https://docs.expo.io/versions/v32.0.0/sdk/asset/#expoassetloadasyncmodules
React Native absolute image path
#1-
Babel Root Import
Babel plugin to change the behaviour of import to root based paths:
https://github.com/mantrajs/babel-root-slash-import
#2-
Package.json
https://github.com/facebook/react-native/issues/3099#issuecomment-221815006
How to get Absolute path of a file in react-native?
I actually figured this out myself. You can get Absolute path in 3 ways.
The most convenient way : Use react-native-document-picker, on selection it will give you a Relative path, something like this content://com.android......
. Pass that Relative path to Stat(filepath) function of the react-native-fetch-blob
library. The object will return absolute path. Append the path with file://
to use it for further operations.
The other 2 ways are by using react-native-image picker and CameraRoll (React Native Library)
I hope this helps !
Edit:
Please make sure you run the app on hardware device rather than Virtual Device to test it.
How can I get the absolute image path in react-native?
you can't access
const path = 'src/img/test.jpg'
in run time because it's bundled within your app
try this :
const dest = `${RNFS.DocumentDirectoryPath}/test.jpg`;
const img = require('src/img/test.jpg');
RNFS.writeFile(dest, img, "base64")
.then(() => FileViewer.open(dest))
.then(() => {
RNFS.readDir(RNFS.DocumentDirectoryPath)
.then((result) => {
console.log('GOT RESULT', result);
})
})
.catch(_err => {
console.log(_err);
});
How to read file from assets folder in react-native?
There is readFileAssets is a method in react-native-fs.
Place your file in android\app\src\main\assets
.If there is no assets
folder
then just create it.
import fs from "react-native-fs";
fs.readFileAssets("folder/file", "base64") // 'base64' for binary
.then(binary => {
// work with it
})
.catch(console.error)
Note: Path must be relative. If android\app\src\main\assets\folder\file
then use folder\file
react-native-fs: How to read local images (Get base64 of local file)
react-native-fs
will only access the files from device storage. So this problem poses a quandary. These files are bundled at build time so how can we access them in development vs production?
My project structure
├── android
├── app
│ └── assets
│ └── images
└── ios
I store my images inside ./app/assets/images/
Development
When in Development or debug the files are served to the device via the metro bundler so they are not actually stored on the device. So accessing them from the devices storage would not be possible. You would have to provide some sort of mocked functionality for when you are developing. It is possible to use __DEV__
to allow different functions to run depending on the environment https://facebook.github.io/react-native/docs/javascript-environment
if (__DEV__) {
// do something in development
} else {
// do something in production
}
Production
From some research it does seem like it is possible to access the files in production.
iOS
What I have discovered is that the files reside in a folder called assets
that are in the MainBundlePath
.
So if you want to access the following file in my local directory ./app/assets/images/image.png
you would need the following file path: RNFS.MainBundlePath + /assets/app/assets/images/image.png
to access it on the device.
You can check to see the file path by looking at the Packaging.log
that is generated with your ipa
.
Android
Android doesn't have a folder called MainBundlePath
that is only on iOS
. I have spent some time researching and looking at the different folders on the device but I was unable to access the images that are bundled. It would seem that they not accessible in the way that we would hope using react-native-fs
.
Possible solutions
rn-fetch-blob
rn-fetch-blob
has functionality for both ios
and Android
to read from the assets directory
To access the files for iOS
you would do something like this:
RNFetchBlob.fs.stat(fs.dirs.MainBundleDir + '/whatever/files/you/added.mp3').then( stats => {...});
And for Android
you would do something like this:
RNFetchBlob.fs.stat(fs.asset('/whatever/files/you/added.mp3').then( stats => {...});
It does give this warning about the assets being compressed by Gradle.
Gradle will compress bundled assets by default. In order to interact with asset files with this module, compression must be disabled. Please see How to access files from assets for more detail.
This could explain why I was unable to find any assets in Android when looking using react-native-fs
You can read more about using rn-fetch-blob
and its filesystem here https://github.com/joltup/rn-fetch-blob#user-content-file-system
Storing the files in the native projects
Rather than relying on the bundler to package up the images for you and put them on the device. You could store copies of them already in the iOS
and Android
projects. This has the bonus that the images would be available in development, however you would storing the images multiple times and it could lead to larger application sizes.
Storing the images as base64
You could store the images as base64 strings in json files and then require these by your application. That would then mean that you would have them already in base64 (so the app doesn't have to do any conversion) but again you would be increasing the size of your application. If it is only a small number of images it may be the easiest option.
Related Topics
How to Add Spacing Between Uitableviewcell
How to Create Custom Calendar in React Native
How to Do Base64 Encoding on Ios
Nsnotificationcenter Addobserver in Swift
Status Bar and Navigation Bar Issue in Ios7
Delete/Reset All Entries in Core Data
Returning Method Object from Inside Block
Enterprise App Deployment Doesn't Work on iOS 7.1
Uiscrollview Horizontal Paging Like Mobile Safari Tabs
Creating a Uicollectionview Programmatically
How to Record Video of Front and Back Camera At a Time in Ios
Best Way to Check If Object Is Out of Bounds in Array
The Simplest Way to Resize an Uiimage
Remove HTML Tags from an Nsstring on the Iphone
Add Uipickerview & a Button in Action Sheet - How