How to access static/local files in react native - file-io

I'm not sure what to call the files, but the context is that I have a bunch of data that I would like to ship with my app. I need to find a way to store this data so that I can load it into the database. (Or better yet, just ship it with a prefilled db)
Here are the solutions that I've seen:
Storing the data in code as a json blob I can't do this because I have quite a lot of data, a few MB or so and I would like to be able to compress it.
Load a file from the public folder
I think this is a create-react-app specific API and I did not use that. But if there's a way to get a public or static folder to read arbitrary files from, that'll be great.
Read a file using react-native-fs
I'm not sure where to put the file in my application so that I can access it. This seems to give me an empty folder to write files to. I don't know where in my app directory I can put the files if I want it to be read by this.
I would also like to have these files compressed, and only loaded when I need them to be. I think using a require('path/to/file.json') loads the file every time I use the app.
How would I go about reading a file from my app?
I'm coding for android if that matters and the database I'm using is watermelondb.

You need to use react-native-asset to put files to your project and access them with require keyword.
Example for file with path ./assets/files/some-file.mp3:
Add or modify react-native.config.js
module.exports = {
project: {
ios: {},
android: {},
},
dependencies: {
},
assets: [
'./assets/files'
],
};
Run npx react-native-asset
Use the file:
const file = require('./assets/files/some-file.mp3')

Related

Webpack: Why there are multiple files with same file name when search the source code?

I am using vue.js (2.6.5) and webpack (5.77.1), and I enabled the source map feature in development env, with simple config as below:
mode: 'development',
devtool: 'eval-cheap-module-source-map',
.....
Well, the source map feature indeed works, but what confuse me is when you search a file name, there will be multiple files with same file name listed, see as below:
Only one of them is the exact original file definition, other files are definitions of render function of vue.js and some others. Every time I need to click on each one of them to check which is the exact original file, this annoys me, does any one know how to only show the exact original file ?

relative link in vue returns with nothing

I have got two components in vue, one with lightbox for images and one for playing audio. I got relative links to the assets but either the images or the audio is being displayed and played. First I thought it was an issue with the component itself but since it doesnt work on either of these it might be something else.
If I provide an absolut url it works however fine for some reason
This doesnt work either when I build the application or locally:
export default {
components: {
VueLitebox,
"vue-audio": VueAudio
},
data() {
return {
// AUDIO
file1: "../assets/music/myfile.mp3",
// LITEBOX
images: [
".../assets/img/myimage.jpg",
This works fine:
export default {
components: {
VueLitebox,
"vue-audio": VueAudio
},
data() {
return {
// AUDIO
file1: "http://mypage.com/music/myfile.mp3",
// LITEBOX
images: [
"http://mypage.com/img/myimage.jpg",
I can of course upload the images and music separate and make it work but it feels a bit inconvenient.
What can be wrong?
UPDATE:
Thanks for the answers. Now I got two methods. And both actually works.
One is to put all my assets in the public folder. That solved it with a link like:
"/assets/img/myimage.jpg",
The other way is to using require.
require("../assets/img/myimage.jpg"),
Both works but is there a prefered way?
You should use require when using assets
file1: require("../assets/music/myfile.mp3")
Without require webpack won’t know that you want to bundle that asset and your path will remain unchanged. Actually webpack knows how to handle this kind of files thru the use of plugins and not out of the box.
Regarding the fact that it works with absolute path and not relative ones.
Your relative path is valid in the local file system on your dev server. When deploying the app you are not running in the local file system, but on the web. Even though relative paths are resolved using a similar algorithm, your results will depend on the URL where the component is used and not on the path of the vue file.
For example if the component is rendered on a URL of the form
https://example.com/list/
The relative path would resolve to https://example.com/assets which is probably what you want. But on the following URL
https://example.com/list/1/
Will resolve to https://example.com/list/assest which isn’t what you’d expect.
Webpack takes care of this problems (to some degree, you need to be sure that you don’t mess up the base tag).

React Native - Create and Export/Download PDF File

I'm making a project in React Native that creates a table with some data, and I need to create a pdf with that table and be able to download/export that pdf.
Currently i'm using https://github.com/christopherdro/react-native-html-to-pdf, but its downloading to cache directory, even if i change to docs.
I was searching and some people say that u need to use file manager to download a pdf.
Can someone help me?
From docs, you have to specify "Documents" directory if you want it to be saved on Documents dir of ios/android.
async createPDF() {
let options = {
html: '<table><tr><th>Firstname</th><th>Lastname</th></tr></table>',
fileName: 'tableTest',
directory: 'Documents',
};
let file = await RNHTMLtoPDF.convert(options)
alert(file.filePath);
}
Since you are creating this table in your react native code, you don't need to download anything from anywhere. Cache directory is your phone's cache directory, so I can't understand from where you want to download the pdf.

react-native filesystem can't find app files

I'm building an app with react-native, and I'm trying to use the react-native-fs module to list out a series of images located in the app folder. The images are located in a folder in the app project folder named 'data', so for example if I want to display one of the images, this works:
<Image source={require('./data/boo.png')} />
However when I try to use react-native-fs to list out all the files in that folder like so:
RNFS.readdir(RNFS.DocumentDirectoryPath+'/data')
.then((result) => {
console.log('GOT RESULT', result);
})
.catch((err) => {
console.log(err.message, err.code);
});
I get the error 'Folder does not exist'. Also when I remove the +'/data' the only result listed is a file by the name of 'ReactNativeDevBundle.js', with a path of '/data/user/0/com.awesomeproject/files/ReactNativeDevBundle.js'. Is this the expected behavior? If this is the expected behavior, and I am doing something wrong, how can I access the file folder I want from within the app? Side question, if I wanted to provide that Image tag with an absolute path, what would that look like.
First, are you creating the data folder in running time? or why do you think that's where the files are?
Second,
Also when I remove the +'/data' the only result listed is a file by
the name of 'ReactNativeDevBundle.js', with a path of
'/data/user/0/com.awesomeproject/files/ReactNativeDevBundle.js'. Is
this the expected behavior?
Yes, this is the expected behavior, RNFS.DocumentDirectoryPath goes directly to /data/user/0/com.awesomeproject/files/, this is where you should create the data folder if you want to keep using the same code you currently have
EDIT:
According to one of the contributors of the package: if your folder is within the javascript-space this package won't work.
If you're using android, you may need to put the files into the assets-folder within the android-folder. Then you should be able to use readDirAssets.
I recommend to read Differences between File Source
Excerpt:
Normal Files: These files are created by your app using fs, or fetch API, you can do any operation on these files.
Asset Files: Compiled into the app bundle so generally they're on
readonly mode

Load Dojo class from string content instead of file

For a very special situation I want to store Dojo classes (i.e. the sources) that I load from remote in the localStorage to have access to them in offline situations (we are talking about a hybrid mobile app). I got everything running but dojo.eval won't let me create the class from a string like this
var data = 'define(["dojo/_base/kernel",...'; // class definition as string
dojo.eval(data);
Any idea how to accomplish this?
If you need to have your app run offline, store the resources (css, images, js) in the app manifest. The manifest file looks like the following.
{
"name": "My App",
"description": "My elevator pitch goes here",
"launch_path": "/",
"icons": {
"128": "/img/icon-128.png"
},
"developer": {
"name": "Your name or organization",
"url": "http://your-homepage-here.org"
},
"default_locale": "en"
}
Your app could require hundreds of modules so for performance and manageability of the manifest, you'll want to create a Dojo build which will reduce the number of js files to one or maybe a couple depending on how you create the build.
I finally managed what I was trying to accomplish. However, I found no way to use the localStorage and to load the classes from a string.
The trick is to load the Dojo class source file from remote using XHR, store it using the Cordova File APIs, getting an URL to the stored file and using this URL in the require().
Does what I want and gives me full control over the cached files.