Reputation: 1571
I am having a hard time understanding the process of downloading a file pdf
or excel
from let's say a nodejs
server in ReactNative
using Expo
.
So far I have gone through a bunch of blog posts/resources on the web but unfortunately I didn't find any solution for this. Most of the blogs are outdated or they don't have any clear implementation for it.
Here are a few approach that I came across.
using rn-fetch-blob
but this does not work with expo as per my findings and each time I tried to integrate it with Expo
, I ended up with error.
The second approach to use expo's FileSharing approach, which kind of works but only if you have a predefined image
or pdf
file.
import { StatusBar } from "expo-status-bar";
import { useEffect, useState } from "react";
import { StyleSheet, Text, View, Button, Alert } from "react-native";
import * as FileSystem from "expo-file-system";
import * as Sharing from "expo-sharing";
export default function App() {
const [downloadProgress, setDownloadProgress] = useState(0);
const [document, setDocument] = useState(null);
async function openShareDialogAsync() {
if (!(await Sharing.isAvailableAsync())) {
alert(`Uh oh, sharing isn't available on your platform`);
return;
}
Sharing.shareAsync(document);
}
async function handleDownload() {
const callback = (downloadProgress) => {
const progress =
downloadProgress.totalBytesWritten /
downloadProgress.totalBytesExpectedToWrite;
setDownloadProgress(progress * 100);
};
let url =
"https://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf";
const downloadResumable = FileSystem.createDownloadResumable(
url,
FileSystem.documentDirectory + "a.pdf",
{},
callback
);
try {
const { uri } = await downloadResumable.downloadAsync();
console.log("Finished downloading to ", uri);
setDocument(uri);
} catch (e) {
console.error(e);
}
}
useEffect(() => {
handleDownload();
}, []);
return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
<Text>Welcome Saroj!</Text>
<Button title="Share" onPress={openShareDialogAsync} />
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});
This implementation kind of works. I am able to share the pdf
but the issue is the pdf link is not generated on the fly, it is something already being generated previosuly. I expect something like we can call an endpoint to a server and the server would either send base64
or binary data
that we can use to make the pdf download to the local storage of the device.
I am open to suggestions and would really appreciate your inputs.
Upvotes: 2
Views: 2369
Reputation: 8300
Use Blob
and FileReader
to download any binary data. Something like this:
const response = await fetch('<link>');
const data = await response.blob()
const reader = new FileReader();
reader.onload = async () => {
const fileUri = FileSystem.documentDirectory + "file";
await FileSystem.writeAsStringAsync(
fileUri, reader.result.split(',')[1],
{ encoding: FileSystem.EncodingType.Base64 }
);
};
reader.readAsDataURL(data);
Upvotes: 1