Google Drive File Download api in node js cannot working? - node.js

I am using google drive file download api for download the file from google drive.
I am using the following code,
var fileId = '1RDrrFGV2fM7jvnxGFileId';
var dest = fs.createWriteStream('./sample.xlsx');
drive.files.get({fileId: fileId, alt: 'media'}, {responseType: 'stream'},
function(err, res){
res.data
.on('end', () => {
console.log('Done');
})
.on('error', err => {
console.log('Error', err);
})
.pipe(dest);
}
);
Downloaded file was empty, How to get the file data.

drive.files.get will return only metadata of the file. Since you're trying to download file and retrieve the content you should use
drive.files.export({fileId: fileId, mimeType: <MIME type of your file>})
You can refer the client documentation https://apis-nodejs.firebaseapp.com/drive/index.html

I got a another solution for download the google drive file. use the following code snippet
var downloadfile="https://docs.google.com/uc?id=" + fileId
return downloadfile;
Browse the downloadfile url to download the file.

Related

How to save the Image using node js rest api from the server

I am working nodejs and angular and I am trying to download an image that I uploaded using nodejs (created a upload folder all the uploaded images are in server side upload folder), I already written an rest api but its not working.
let me explain the exact situation, there is a form for teacher for uploading the assignment he/she upload the assignment in the form of image now students can see the assignment uploaded by the teacher I also want to give the download option so the image can get download to the local machine.
I am using mime-types for this
download api
app.get("/download/:filename", (req, res) => {
console.log(req.body);
var imagename = req.params.filename;
var file = __dirname + "/uploads/" + imagename;
var filename = path.basename(file);
var mimetype = mime.lookup(file);
res.setHeader('Content-disposition', 'attachment; filename=' + filename);
res.setHeader('Content-type', mimetype);
res.download(file)
var filestream = fs.createReadStream(file);
filestream.pipe(res);
})
from the angular side I am passing the object that contain name of the image that present in server side, folder name is upload
service.ts
(Right now I am passing the static name)
private downloadImageUrl = "http://localhost:3000/download/1592945165166-java-1.png";
downloadImage(assignment: Assignment) {
return this.http.get(this.downloadImageUrl, {
observe: "body",
responseType: 'blob'
})
}
component.ts
onDownload(index: number) {
console.log(this.assignment[index])
this.teacherServ.downloadImage()
.subscribe(
res => console.log(res),
err => console.log(err)
)
}
I want to image get downloaded in the local system of download folder
No error message is there but still image is not downloaded to my local storage of download folder.
UPDATE:
I successfully able to save the image using the file-saver in angular-7, I will share the code here but still there is a one problem, problem is jpg format images are getting saved as a file format or an unknown format (basically I am unable to open it.), there is no problem with png format. So I want to how how can I save the jpg as well as png format of image using file-saver
service.ts
private downloadImageUrl = "http://localhost:3000/download";
downloadImage(file: any){
return this.http.post(this.downloadImageUrl, file, {
responseType : 'blob',
headers : new HttpHeaders().append('content-type','application/json')
})
}
component.html
<td>
<img
height="92px"
style="cursor: pointer"
src="http://localhost:3000/{{receivedAssignment.assignment}}"
alt="not found"
(click)="onDownload(i)">
component.ts
onDownload(index: number) {
console.log(this.assignment[index].assignment)
var filename = this.assignment[index].filename
this.teacherServ.downloadImage(this.assignment[index]) //sending the particular assignment that I want to download.
.subscribe(
(data) => {
if(data && data != undefined && data != null) {
saveAs(data, filename)
}
}
)
}
app.js //nodejs api
app.post('/download', function(req,res,next){
console.log(req.body.assignment);
console.log(path.join(__dirname,'uploads','/'+req.body.assignment))
filepath = path.join(__dirname,'uploads','/'+req.body.assignment);
res.sendFile(filepath);
});
So, this method is working for png images but not for jpg image, please let me know why? and how can I solve this?
Thanks.

NodeJS generate pdf and save to firebase storage. Can't open file

I've been stuck on this problem for awhile now and can't seem to figure out why this file isn't being uploaded to firebase correctly. I'm using the code below in firebase functions to generate a document, then I convert that document to a stream, finally I create a write stream declaring the path that I want the file to be written to and pipe my document stream to the firebase storage WriteStream.
Example 1: PDF uploaded from file system through firebase console. (Link works and displays pdf)
Example 2: PDF generated in firebase functions and written to storage using code below
Considerations:
I know the PDF is valid because I can return it from the function and see it in my web browser and everything is as I would expect.
When trying to open the bad file it doesn't display anything and redirects me back to the overview screen.
const pdfGen = require("html-pdf");
pdfGen.create(html, { format: "Letter" }).toStream(function (err, stream) {
if (err) return res.status(500).send(err);
var file = storage.bucket()
.file(job.jobNum + "/quote-doc.pdf")
.createWriteStream({
resumable : false,
validation : false,
contentType: "auto",
metadata : {
'Cache-Control': 'public, max-age=31536000'}
});
stream.pipe(file)
.on('error', function(err) {
return res.status(500).send(err);
})
.on('finish', function(data) {
stream.close();
file.end();
res.end();
console.log('finished upload');
});
});

Firebase Cloud Function Serving Local File for Download

I created cloud function that generates an xlsx file, I need the user to download that file after it's generated.
Method 1: Upload to Bucket, then redirect
So far i've tried uploading the file to a bucket using this API, and then redirect him to the bucket file url, I also double checked the bucket name using this API, but I get the same error every time:
{"error":{"code":500,"status":"INTERNAL","message":"function crashed","errors":["socket hang up"]}}
Portion of the code that contains uploading to bucket:
const { Storage } = require('#google-cloud/storage');
const storage = new Storage();
await storage.bucket('bucket-name').upload('myfile.xlsx', {
gzip: false,
});
Portion of the code that proves file exists:
fs.access('myfile.xlsx', fs.constants.F_OK, (err) => {
console.log(`${file} ${err ? 'does not exist' : 'exists'}`);
});
I also checked if the library "#google-cloud/storage" reads the file, and it reads it correctly and gets the file size right.
Method 2: Direct Download
Download the file directly, the problem is that every doc online for nodejs to download a local file to the user is setting up a custom server to download the file, but i'm using firebase, so it's not in control of that server.
Just wanted to add more detail to the answer, since there's no need to write into a file and read from it to download it's data, simply take the data and send it, using the few lines below.
res.setHeader('Content-Type', 'application/vnd.openxmlformats');
res.setHeader("Content-Disposition", "attachment; filename=" + fileName);
res.end(fileData, 'binary');
If your excel file is created and should be returned to the client as a response to an HTTP request (calling to an API endpoint) then this is how you can do it.
export const getExcelFile = functions.https.onRequest(async (request, response) => {
// ...
// Create your file and such
// ..
await storage.bucket('bucket-name').upload('myfile.xlsx', {
gzip: false,
});
response.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
response.send(fs.readFileSync('myfile.xlsx'));
return null;
});
Otherwise, if the excel file is created as a response to an event, and you want the user to download the file at another time, then you create a download link and serve it to the user in any way you want.
// ...
// Create your file and such
// ..
const [file] = await storage.bucket('bucket-name').upload('myfile.xlsx', {
gzip: false,
});
const [downloadUrl] = await file.getSignedUrl({
action: 'read',
expires: '20-03-2019' // Link expiry date: DD-MM-YYYY
});
console.log(downloadUrl);

Display PDF file in ReactJS that is received from a Node.js server?

I am trying to build a system where a user can store pdf files on a server, and another user can view those pdf files by using a simple click on a file link.
I am trying to store a file in a MySQL database and retrieve it using app.get(). I have successfully stored the file in the database using BLOB, but when I try to retrieve it, it is in some other format.
I have also tried to store the file in local folder ./uploads using 'express-fileupload', but that also doesn't seem to work when I try to retrieve the file location. After receiving the file location I am sending it back to my React app, and then try to open it using embed and iframe tags.
I have also tried 'react-pdf', 'simple-react-pdf', but nothing seems to work.
Below is the code that is written on server side that is sending the pdf file. I have also tried sending the location of pdf file that is stored in location provided in the code below. But that also doesn't work.
app.get('/getFile', (req, res) => {
const {email, courseid, filename} = req.query;
console.log(email);
console.log(courseid);
console.log(filename);
var filePath = `${__dirname}`+'/uploads/'+`${filename}`;
fs.readFile(filePath , function (err,data){
console.log(data);
res.contentType("application/pdf");
res.send(data);
});
});
This worked for me:
Node:
app.get("/getFile", function(req, res) {
res.sendFile(__dirname + "/test.pdf");
});
React:
axios(`http://localhost:5000/getFile `, {
method: "GET",
responseType: "blob"
//Force to receive data in a Blob Format
})
.then(response => {
//Create a Blob from the PDF Stream
const file = new Blob([response.data], {
type: "application/pdf"
});
//Build a URL from the file
const fileURL = URL.createObjectURL(file);
//Open the URL on new Window
window.open(fileURL);
})
.catch(error => {
console.log(error);
});

Sending Zip file from server to client browser with Express and Archiver

I am a beginner with Node and I am trying to figure out how to create a zip file at the server then send it to the client and then download the zip file to the user's browser. I am using the Express framework and I am using Archiver to actually do the zipping. My server code is the following which was taken from Dynamically create and stream zip to client
router.get('/image-dl', function (req,res){
res.writeHead(200, {
'Content-Type': 'application/zip',
'Content-disposition': 'attachment; filename=myFile.zip'
});
var zip = archiver('zip');
// Send the file to the page output.
zip.pipe(res);
// Create zip with some files. Two dynamic, one static. Put #2 in a sub folder.
zip.append('Some text to go in file 1.', { name: '1.txt' })
.append('Some text to go in file 2. I go in a folder!', { name: 'somefolder/2.txt' })
.finalize();
});
So its zipping two text files and returning the result. On the client side I am using the following function in a service to actually call that endpoint
downloadZip(){
const headers = new Headers({'Content-Type': 'application/json'});
const token = localStorage.getItem('token')
? '?token=' + localStorage.getItem('token')
: '';
return this.http.get(this.endPoint + '/job/image-dl' + token, {headers: headers})
.map((response: Response) => {
const result = response;
return result;
})
.catch((error: Response) => {
this.errorService.handleError(error.json());
return Observable.throw(error.json());
});
}
and then I have another function which calls downloadZip() and actually downloads the zip file to the user's local browser.
testfunc(){
this.jobService.downloadZip().subscribe(
(blah:any)=>{
var blob = new Blob([blah], {type: "application/zip"});
FileSaver.saveAs(blob, "helloworld.zip");
}
);
}
When testfunc() is called, a zip file is downloaded to the user's browser however when I try to unzip it it creates a zip.cpgz file which then turns back into a zip file when clicked in an infinite loop which indicates that some kind of corruption happened. Can anyone see where I went wrong here?

Resources