How to upload files from file manager without using iCloud? - react-native

I want to upload doc and pdf files from my React Native app. I used React Native document picker but it works with iCloud and I want to select files from the file manager.
Here is my code:
import { DocumentPicker, DocumentPickerUtil } from 'react-native-document-picker';
selectFile(type,index='') {
DocumentPicker.show({
filetype: [DocumentPickerUtil.allFiles()],
},(error,res) => {
console.log(
res.uri,
res.type, // mime type
res.fileName,
res.fileSize
);
});
}

Related

Save a genrated pdf file in react native in interal memory in React Native Expo

I am trying to generate pdf and trying to download the same generated pdf in React Native Expo. I am not able to find any solution that lets me store file directly in my phone memory.The only solution i am getting is using expo-share share the generated pdf . Is there any way to do it ?
This is what my SavePDF functions look like
const SavePDF = async()=> {
const file = await printToFileAsync({
html: "Hello World",
base64: false,
})
await shareAsync(file.uri);
}

Download txt file from text in React Native

I'm trying to Download txt file from a text but that function is not working fine.
Txt Function
import RNFS from 'react-native-fs';
const txtDownload = () => {
let path = `${RNFS.DocumentDirectoryPath}/${filename}.txt`;
RNFS.writeFile(path, `Here is text`, 'utf8').then((res) => {
Toast('File saved successfully');
}
).catch((err) => {
Toast(err);
});
}
It returns File saved successfully but I can't find file
Log the path and check the location where it's trying to store. For me, it shows the location as below when I try to store in ${RNFS.DocumentDirectoryPath}/help.txt
/data/user/0/com.sample/files/help.txt
I suspect you were checking in the Documents folder. I don't know if you can write to the Documents folder. But it works for the Download folder using RNFS.DownloadDirectoryPath.

React-native: download and unzip large language file

A multilingual react-native app. Each language bundle is ~50MB. It doesn't make sense to include all of them in a bundle. So, what do I do about it?
I assume the right way to go here is to download the respective language files upon language selection.
What do I do with it next? Do I suppose to store it using AsyncStorage or what?
Briefly explaining, you will:
Store JSON as ZIP in Google Storage (save memory/bandwidth/time)
Unzip file to JSON (in RN)
Store JSON in AsyncStorage (in RN)
Retrieve from AsyncStorage (in RN)
[Dependencies Summary] You can do this, using these deps:
react-native
react-native-async-storage
rn-fetch-blob
react-native-zip-archive
Tip: Always store big language json in zip format (this can save up to 90% of size).
I made a quick test here: one 3.52MB json file, turned out a 26KB zipped file!
Let's consider that yours stored zip file, can be accessed by using a public url, eg: https://storage.googleapis.com/bucket/folder/lang-file.zip.
Install and link all above RN deps, it's required to get this working.
Import the deps
import RNFetchBlob from 'rn-fetch-blob';
import { unzip } from 'react-native-zip-archive';
import AsyncStorage from '#react-native-community/async-storage';
Download the file using rn-fetch-blob. This can be done using:
RNFetchBlob
.config({
// add this option that makes response data to be stored as a file,
// this is much more performant.
fileCache : true,
})
.fetch('GET', 'http://www.example.com/file/example.zip', {
//some headers ..
})
.then((res) => {
// the temp file path
console.log('The file saved to ', res.path())
// Unzip will be called here!
unzipDownloadFile(res.path(), (jsonFilePath) => {
// Let's store this json.
storeJSONtoAsyncStorage(jsonFilePath);
// Done!
// Now you can read the AsyncStorage everytime you need (using function bellow).
});
});
[function] Unzip the downloaded file, using react-native-zip-archive:
function unzipDownloadFile(target, cb) {
const targetPath = target;
const sourcePath = `${target}.json`;
const charset = 'UTF-8';
unzip(sourcePath, targetPath, charset)
.then((path) => {
console.log(`unzip completed at ${path}`)
return cb(path);
})
.catch((error) => {
console.error(error)
});
}
[function] Store JSON in AsyncStorage:
function storeJSONtoAsyncStorage (path) {
RNFetchBlob.fs.readFile(path, 'utf-8')
.then((data) => {
AsyncStorage.setItem('myJSON', data);
});
}
Retrieve JSON data from AsyncStorage (everytime you want):
AsyncStorage.getItem('myJSON', (err, json) => {
if (err) {
console.log(err);
} else {
const myJSON = JSON.parse(json);
// ... do what you need with you json lang file here...
}
})
That's enough to get dynamic json lang files working in React Native.
I'm using this approach to give a similar feature to my i18n'ed project.
Yes you are right to make the translation file downloadable.
You can store the downloaded file in the document directory of your app.
After that you can use a package to load the translations. For instance
https://github.com/fnando/i18n-js.
I would also suggest taking a look at the i18n library which is a standard tool for internationalisation in JavaScript.
Consider taking a look at this documentations page where you can find an option of loading a translation bundle or setting up a backend provider and hooking into it.
Also, to answer the storage question, if you do not plan on setting up a backend: AsyncStorage would be an appropriate place to store your key - translation text pairs.

When using Expo for React Native, is there any way to read the mime-type from a file?

React Native - File Type is great but needs to be linked, and thus, won't work with a managed Expo project.
How can you read the file mime type when using Expo managed projects?
You can simply use the mime Javascript library to get the mime-type from the file name: https://www.npmjs.com/package/mime
import * as mime from 'mime';
const mimeType = mime.getType('my-doc.pdf') // => 'application/pdf'
If you are using the DocumentPicker to get the file, you can obtain the file name from the result directly:
const result = await DocumentPicker.getDocumentAsync();
if (result.type === 'cancel') {
return;
}
const fileName = result.name;
const mimeType = mime.getType(fileName);

Export whatsapp messages to react-native app

I'm trying to access whatsapp messages from my device with react-native. Accessing them directly seems impossible so I was looking into the possibility of exporting the messages and importing them in my app. The options which are currently provided by whatsapp sharing menu lack any direct download option.
Is there a way to add my app to the whatsapp sharing menu? Or is there an easy way to import these messages?
You can use https://github.com/meedan/react-native-share-menu this library for exporting chat from Whatsapp. When you export chat file from WhatsApp, your app will show on the share dialog. After that, you can open that file from your app like below
ShareMenu.getSharedText((text :string) => {
if (text && text.length) {
if (text.startsWith('content://media/')) {
//this will be a media
} else {
content = this.readFile(text)
}
}
})
Then you can read the content of that file using RNFS library
readFile = async (path) => {
try {
const contents = await RNFS.readFile(path, "utf8");
return("" + contents);
} catch (e) {
alert("" + e);
}
};
After getting the content of the chat, you can parse that chats.
We had the same issue when building a Website to analyze WhatsApp chats, as with android you can not save the exported chat on the device.
Our solution was to use a PWA (Progressive Web App) and listen share Events.
When somebody now installs the PWA, they can share the export with the App directly. (Currently, this is only supported for Android with Chrome, as Apple is heavily against PWAs)
Our implementation:
if (workbox) {
workbox.addEventListener("message", (m) => {
// eslint-disable-next-line no-prototype-builtins
if (_this.$route.query.hasOwnProperty("receiving-file-share")) {
let files = m.data.file;
// currently only the first file, but ultimately we want to pass all files
_this.$refs.filehandler.processFileList(files, true);
}
});
workbox.messageSW("SHARE_READY");
}