I am creating pdf in IONIC 4. Following code is working on web and android but not on IOS. In IOS it is giving alert("Error creating file: " + err);
.catch(err => {
this.runloading = 'hide';
alert("Error creating file: " + err);
throw err;
});
if (this.platform.is("cordova")) {
this.pdfObj.getBuffer(buffer => {
var blob = new Blob([buffer], { type: "application/pdf" });
this.file
.writeFile(this.file.externalRootDirectory, "pro.pdf", blob, {
replace: true
})
.then(fileEntry => {
this.fileOpener
.open(
this.file.externalRootDirectory + "pro.pdf",
"application/pdf"
)
.catch(err => alert("Please install pdf viewer"));
this.runloading = 'hide';
})
.catch(err => {
this.runloading = 'hide';
alert("Error creating file: " + err);
throw err;
});
});
} else {
pdfmake.createPdf(docDefinition).open();
// this.pdfObj.download();
this.runloading = 'hide';
}
See this message below. There is a bug that prevents uniform experience for local file downloads on iOS.
Two choices:
1. Upload pdf to server and redownload it.
2. Await for iOS13
https://github.com/eligrey/FileSaver.js/issues/375#issuecomment-460318259
Related
My api as follows
router.post("/upload", async (req, res) => {
if (!req.files || Object.keys(req.files).length === 0) {
return res.status(400).send("No files were uploaded.");
}
console.log(req.files)
let file = req.files.upload;
let uploadPath = __dirname + "/../public/" + file.name;
file.mv(uploadPath, function (err) {
if (err) {
console.log(err)
return res.status(500).send(err)
}
res.sendStatus(200);
});
});
My react component
<CKEditor
editor={ClassicEditor}
config={{
ckfinder: {
uploadUrl: "/api/upload",
},
}}
data={props.state.tech.assess_info}
onChange={(event, editor) => {
..
}}
/>
Currently when I upload image from CKeditor, image is successfully uploaded(written to "public/{filename}" on server side). However CKEditor error popups and stating "cannot upload". I believe CKeditor is expecting specific response code, not just HTTP status 200. What do you guys think?
Ckeditor is expecting following response from API.
res.status(200).json({
uploaded: true,
url: `/uploads/${file.name}`,
});
Whole api code if anyone needs.
// Upload a file
router.post("/upload", async (req, res) => {
if (!req.files || Object.keys(req.files).length === 0) {
return res.status(400).send("No files were uploaded.");
}
let file = req.files.upload;
let uploadPath = __dirname + "/../public/uploads/" + file.name;
file.mv(uploadPath, function (err) {
if (err) return res.status(500).send(err);
res.status(200).json({
uploaded: true,
url: `/uploads/${file.name}`,
});
});
});
I'm trying to upload an xlsx to firestore storage ,I'm using react-native-document-picker to pick the file from ExternalStorageDirectoryPath so when just log the files uri I don't get the error but as soon as try to upload the file it throws the error .
relevant code :
const uploadFile=async ()=>{
try {
const res = await DocumentPicker.pick({
type: [DocumentPicker.types.allFiles],
});
const task = Storage().ref('catalogue/'+ res.name).putFile(res.uri);
task.on('state_changed',
sn =>{},
err=>console.log(err),
() => {
console.log('excel uploaded!'+res.name)
Storage()
.ref("catalogue").child(res.name).getDownloadURL()
.then(url => {
console.log('uploaded excel url', url);
}).catch(err=>console.log(err))
}
)
await task
} catch (err) {
if (DocumentPicker.isCancel(err)) {
// User cancelled the picker, exit any dialogs or menus and move on
} else {
throw err;
}
}
}
`
I already included the required permissions in my AndroidManifest.xml file and rebuilt the project
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS"/>
but still I'm getting this error :
Permission Denial: reading com.android.externalStorageProvider uri content://com... requires android.permission.MANAGE_DOCUMENTS, or grantUriPermission()
I had a similar problem with the frameworks Qt with the last android SDK version, I've fixed the problem by adding requestLegacyExternalStorage in the manifest (pat Application):
<application android:requestLegacyExternalStorage="true" android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" //...
it's related to a recent change in the permission system:
https://developer.android.com/about/versions/11/privacy/storage
Here is my code that solved this issue:
handleFileSelection=async(props)=>
{
try
{
const response = await DocumentPicker.pickMultiple({
presentationStyle: 'fullScreen',
allowMultiSelection: true,
copyTo: 'cachesDirectory',
});
await this.pickImageAndUpload(response[0].fileCopyUri)
} catch (err) {console.warn(err)}
}
pickImageAndUpload = async(uri) => {
const uploadTask = storage().ref().child(`/usersChatImages/${Date.now()}`).putFile(uri)
uploadTask.on('state_changed',
(snapshot) => {
var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
},(error) => { alert("error uploading image")},() => {
uploadTask.snapshot.ref.getDownloadURL().then((downloadURL) =>
{
alert(downloadURL)
}).catch((err)=>{alert("YESSS")}); });
}
Im working on react native fetch blob to download the file. The file basically are in my nodejs server.
I have tried to get it from post man and its successfully working. But when i attached the api into rn-fetch-blob it shows me download failed even file exists. I have checked 10 time my installation is correct there is no issue there. Can any body help me to get out of this.
SO this is my node api router.post('/download-proof', documents.proofDownload);
proofDownload: (req, res)=> {
let filepath = path.join(__dirname,'../../../documents/')+req.body.filename
res.setHeader('Content-Disposition', 'attachment; filename=' + req.body.filename);
res.setHeader('Content-Transfer-Encoding', 'binary');
res.setHeader('Content-Type', req.body.mimetype);
res.download(filepath)
},
its working fine in postman
This one is rn-fetch-blob
let options = {
fileCache: true,
appendExt: getExt,
addAndroidDownloads: {
useDownloadManager: true, // setting it to true will use the device's native download manager and will be shown in the notification bar.
notification: true,
description: 'Downloading file.',
path:
pathToDir +
`/${file.filename}` ,
},
path:
pathToDir +
`/${file.filename}` ,
notification: true,
};
console.log(file," docs")
console.log(options.path, pathToDir,"options")
let body = {
filename: file.filename,
mimetype: file.mimetype
}
console.log(body, "line no 62")
let url = `http://3.21.33.146:3000/download-proof`;
console.log(url);
config(options)
.fetch("POST", url,{}, JSON.stringify(body))
.progress({interval: 250}, (received, total) => {})
.then((res) => {
console.log(res, "fetch blob response")
}).catch((err) => {
console.log(err)
})
} else {
Alert.alert(
"Permission Denied!",
"You need to give storage permission to download the file"
);
}
} catch (err) {
console.log(err);
}
}
It gives me status code 16 error don't know what the problem is.
I am a beginner with fetch and trying to get some data from JSON-server to my react native app but it gave me the same error always... "network request failed"
I tried to use Ip instead of localhost like "http://192.168.x.x:3000" but nothing changed and my expo is 192.168.x.x:19000. what I forgot to do? and why this error always happened?
export const fetchDishes = () => (dispatch) => {
dispatch(dishesLoading());
return fetch("http://192.168.1.5:3000/dishes")
.then(
(response) => {
if (response.ok) {
return response;
} else {
var error = new Error(
"Error " + response.status + ": " + response.statusText
);
error.respone = response;
throw error;
}
},
(error) => {
var errmss = new Error(error.message);
throw errmss;
}
)
.then((respone) => respone.json())
.then((dishes) => dispatch(addDishes(dishes)))
.catch((error) => dispatch(dishesFailed(error.message)));
};
My Expo screen
I am new to ionic framework, actually I am getting byte array as response from back end service and converting it to blob. How can I save it to PDF in ionic?
var blob = new Blob([res], { type: 'application/pdf' });
Here res is the response (byte array) from the service.
Code
var blob = new Blob([res], { type: 'application/pdf' });
let fileName="Receipt.pdf";
let filePath = (this.platform.is('android')) ?
this.file.externalRootDirectory : this.file.cacheDirectory;
this.file.writeFile(filePath, fileName, blob, { replace: true }).then((fileEntry) => {
console.log("File created!");
this.fileOpener.open(fileEntry.toURL(), 'application/pdf')
.then(() => console.log('File is opened'))
.catch(err => console.error('Error openening file: ' + err));
})
.catch((err) => {
console.error("Error creating file: " + err);
throw err;
});
Thanks in advance.
In order to SAVE the PDF, you'll need to use some cordova plugins. Ionic has some nice wrappers around these here. Check out the File, File Transfer, and File Opener plugins.
Here's some example code you could use once you get these plugins incorporated into your project:
var blob = new Blob([res], { type: 'application/pdf' });
//Determine a native file path to save to
let filePath = (this.appConfig.isNativeAndroid) ? this.file.externalRootDirectory : this.file.cacheDirectory;
//Write the file
this.file.writeFile(filePath, fileName, blob, { replace: true }).then((fileEntry: FileEntry) => {
console.log("File created!");
//Open with File Opener plugin
this.fileOpener.open(fileEntry.toURL(), data.type)
.then(() => console.log('File is opened'))
.catch(err => console.error('Error openening file: ' + err));
})
.catch((err) => {
console.error("Error creating file: " + err);
throw err; //Rethrow - will be caught by caller
});