Link to the File Structure Photo
So I'm currently learning React Native and assuming a file structure shown in the photo. I would like the user to click a button such that the button saves some text to a txt file under resources. How would I go about doing that?
I have tried AsyncStorage, fn-fetch-blob, react-native-filesystem but they have failed (not sure if those libraries are meant to be for specific file directories on your phone device)
What I have so far is a code shown below where if the user clicks the "Create file" button, then it saves to a text file called "my-file.txt" under the same directory as where the current .js file is, which well doesn't work
import FileSystem from 'react-native-filesystem'
export default class SaveData extends React.Component {
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this.createFile}>
<Text>Save to file</Text>
</TouchableOpacity>
</View>
);
}
createFile = async () => {
const fileContents = 'This is some content.';
await FileSystem.writeToFile('./my-file.txt', fileContents);
}
}
What you are trying to do here is not possible. There is no way of accessing these directories when your app is running. This is not the same as when you are running on a computer (a node.js app for example). This file structure will not be available when you are running in a native environment.
Async storage is not used to save files. It is used to save values, so it will never work for what you are trying to accomplish here.
The closest thing to what you are trying to do would be to use react-native-fetch-blob and store the file in the file system of the device, which is also the correct way of storing a file on a mobile device.
Related
am using React Native Expo and I was browsing the web to find a way to download assets, and files to my react native project and came across with this post How to Download image in react native
When the user clicks the download button I want assets/files to be downloaded and stored inside the app not directly on the user's phone. I mean I don't want the users to view the downloaded files or delete them manually.
I just want the downloaded assets/files to be accessible by the React Native app. Am doing this to make the app work offline.
Once the users downloaded the assets/files, the app can use the downloaded assets/files. How can I accomplish that?
Thank you in advance!
If you are using expo managed workflow, then rn-fetch-blob will not work for you.
In that case, Expo File System is probably your way to go.
Firstly, install expo-file-system. See this
Next, for saving files and not letting users delete them manually, store them inside the cache-directory like this
import * as FileSystem from 'expo-file-system';
const downloadAssets = async () => {
let name = "Samplefile.jpg";
const result = FileSystem.createDownloadResumable(
url_Of_the_File_You_Want_to_Download,
FileSystem.cacheDirectory + name
);
const response = await result.downloadAsync();
if (response.status === 200) {
// File successfully saved
} else {
// Some error
}
};
To access this file in your app simple execute this function
import * as FileSystem from 'expo-file-system';
const getFiles = async () => {
const CacheDir = await FileSystem.readDirectoryAsync(
FileSystem.cacheDirectory
);
console.log(CacheDir); //Files are stored here
};
I am using Expo for my React Native Application. console.log(responseJson) writes the App.js output to the my zsh terminal however my Json gets truncated with the following message.
...(truncated to the first 10000 characters)
I want to be able to view the entire Json by logging the output to a .txt file on my app directory.
Is there a solution or workaround without having to eject my Expo app to ExpoKit?
Alternative solution:
install json-server
npm install -g json-server
create a new file for logs:
echo '{"logs": []}'> logs.json
start json-server:
json-server logs.json
now in your code you can store:
let veryLargeTextWorks = "1234567890";
for (let i = 0; i < 11; i++) {
veryLargeTextWorks += veryLargeTextWorks;
}
// veryLargeTextWorks.length == 20480
axios.post("http://localhost:3000/logs", {
date: new Date(),
msg: veryLargeTextWorks
});
I have different solution, you can view complete logs in ScrollView.
You need to save response JSON using useState and then write code like this in ScrollView.
return(<View style={styles.container}>
<ScrollView>
<Text>{ JSON.stringify(responseJson) }</Text>
</ScrollView>
</View>)
I have checked this code. It will show complete logs without any problem.
I am working on a react native project. I need to store the captured images in the custom folder.
I am using react native fs library for that. I am able to create the image in the desired directory but I am not able to see those images in my iphones' file directory.
Here is my code I am using to store the images.
async moveAttachment(capturedImagePath) {
$filePathDir = `${RNFS.DocumentDirectoryPath}/myapp/myfilename`;
$filePath = `${$filePathDir }/myfilename.png`;
return new Promise((resolve, reject) => {
RNFS.mkdir(filePathDir)
.then(() => {
RNFS.moveFile(capturedImagePath, filePath )
.then(() => resolve(dirPictures))
.catch(error => reject(error));
})
.catch(err => reject(err));
});
}
I am able to see the image in my simulator's document directory but not able to see in the iPhone > files directory.
Please help me to figure this out.
You should be able to enable it by updating your Info.plist. You need to add two keys:
UIFileSharingEnabled and LSSupportsOpeningDocumentsInPlace should both be added and set to YES.
UIFileSharingEnabled: Application supports iTunes file sharing
LSSupportsOpeningDocumentsInPlace: Supports opening documents in place
This will allow your DocumentsDirectory to be opened in iTunes and it should also allow you to share your files via the Files application.
You can read more about LSSupportsOpeningDocumentsInPlace here
In iOS 11 and later, if both this key and the UIFileSharingEnabled key
are YES, the local file provider grants access to all the documents in
the app’s Documents directory. These documents appear in the Files
app, and in a document browser. Users can open and edit these document
in place.
Note that any item you save in the Documents directory will be accessible.
I am currently trying to open an image that's saved in the cache from the react-native-camera module. According to this Open android Gallery App from react native app they managed to do it when they passed in the content:// url instead of the file:// url, but after some research I can't find anything on converting file uris to content - only the opposite. I can get the image file paths by:
import RNFS from 'react-native-fs'
import { Linking } from 'react-native'
RNFS.readDir(RNFS.CachesDirectoryPath)
.then(arr => RNFS.readDir(arr[0].path)) // The Camera directory
.then(arr => arr.forEach(item => {
const contentURI = somehowConvertPathToContentURI(item.path)
Linking.canOpenURL(contentURI)
.then(able => able ? Linking.openURL(contentURI) : console.log('No application available'))
.catch(console.log)
}))
.catch(console.log)
A logged path would be /data/user/0/com.myapp/cache/Camera/ad8db2ca-4739-47cc-b18d-c5147c8c26e0.jpg. Adding file:// in front will give me the file uri, what about content://?
As a side note, I'm able to directly show the image if I read and convert it to base64 with react-native-fs, then providing the base64 to react-native's <Image> component - but I'd like to open the app with a gallery application
i know its possible to store data using local storage for a web app but how would i do this for a react native app. the app I've made allows the user to enter a phone number into the input field and it will call that number. I also have a login page. I would like the last number they entered into the input field still be there when they re open the app. heres the code below
<View>
<Text style={styles.phoneNumberTitle}>PHONE NUMBER</Text></View>
<TextInput style={styles.inputs}
ref={(el)=>{this.recipient=el;}}
onChangeText={(recipient)=>this.setState({recipient})}
value={this.state.recipient}/>
<Button title="CALL"
style={styles.callButtCont}
onPress={this.setTimer.bind(this)} />
UPDATE:
AsyncStorage is Deprecated. Use react-native-community/react-native-async-storage instead.
ORIGINAL ANSWER:
AsyncStorage is a simple, unencrypted, asynchronous, persistent, key-value storage system that is global to the app. It should be used instead of LocalStorage.
import AsyncStorage at the top :-
import { AsyncStorage} from 'react-native'
set like this :-
AsyncStorage.setItem("recipient", this.state.recipient);
and access like this :-
AsyncStorage.getItem("recipient").then((value) => {
alert("Get recipient >> ", value);
}).done();
Reference: https://facebook.github.io/react-native/docs/asyncstorage.html