Optimizing PDF Handling in Node.js with Firebase Storage and Buffer
Prologue:
A Challenge Emerges In the vast realm of software development, where client demands shape the landscape, I encountered a formidable challenge: to tame a sprawling PDF document. Armed with Firebase Storage and Buffer, I embarked on a quest to enhance PDF delivery, ensuring swift loading times and seamless user experiences.
Chapter One: The Adventure Begins
In a digital domain, an infamous PDF, known as “example.pdf,” wreaked havoc with its cumbersome size. Determined to restore harmony, I ventured into the code, equipped with tools and resolve. Here’s how the saga unfolded:
import { RequestHandler } from 'express';
import { Config } from '../../../utils/config';
import { getFilePath } from '../../../utils/helpers/common';
const { Storage } = require('@google-cloud/storage');
import * as mime from 'mime';
const { PDFDocument } = require('pdf-lib');
export const getBookFileWithRange: RequestHandler = async (req, res) => {
const dummyFileURL = 'https://dummy-firebase-storage.com/books/example.pdf';
const filename = 'example.pdf';
const storage = new Storage();
try {
const bucket = storage.bucket(Config.storageBucket);
const file = await bucket.file(filename);
const [fileBuffer] = await file.download();
const firstDonorPdfDoc = await PDFDocument.load(new Uint8Array(Buffer.from(fileBuffer)));
const pdfDoc = await PDFDocument.create();
let start = Number(req.query.startPage), pageCount = 0, end = Number(req.query.endPage);
for (start - 1; start - 1 <= end - 1; start++) {
const [page] = await pdfDoc.copyPages(firstDonorPdfDoc, [start - 1]);
pdfDoc.insertPage(pageCount, page);
pageCount++;
}
const pdfBytes = await pdfDoc.save();
const contentType = mime.getType(filename);
res.set('Content-Type', contentType?.toString());
return res.status(200).send(Buffer.from(pdfBytes));
} catch (error) {
console.error('Error encountered:', error);
return res.status(500).send('Error downloading file');
}
};
Chapter Two: The Tools of the Trade
Our journey leverages mighty allies:
- Express: Our steadfast framework for navigating web routes.
- pdf-lib: A powerful library for PDF manipulation, allowing us to deftly split and reassemble documents.
- Firebase Storage: Our vault in the cloud, securing and serving files with ease.
- mime: A small but crucial library that reveals the nature of our PDF to the world.
Chapter Three: Bridging Code and Server
We weave our spell into the server, integrating PDF functionalities with ease:
import cors from 'cors';
import express from 'express';
import { getBookFileWithRange } from './handlers/get/books/getBookFile';
const app = express();
app.use(cors());
app.get('/book/file/by/url/:filename', getBookFileWithRange);
app.listen(3000, () => {
console.log('Server is humming on port 3000');
});
This incantation sets the stage for our PDF service, ready to respond to those in need.
Chapter Four: The Call to Action
With our server at the ready, we beckon to our digital creation, invoking its service to deliver bespoke PDFs. Our endpoint awaits, ready to transform PDFs at our command.
Chapter Five: A Noble Conclusion
Armed with Firebase Storage, pdf-lib, and Buffer, we conquer lag and deliver pristine PDFs. Our code, a symphony of precision, ensures users enjoy seamless interactions.
As our tale concludes, I, a humble developer, hope this guide serves you well in your digital quests. Share in the knowledge, and may your code ever be efficient and mighty.