title: How to Save and Retrieve a pdf file in MongoDB in NodeJS
body: <p>I have an issue where I have saved a small pdf file (~128KB) that is created in my Node.js server backend using Express to a document in Mongodb. I didn't use the Mongo GridFS because the files will always be under the 16MB limit. The collection has a schema of the following:</p>
  
  <pre><code>const mongoose = require('mongoose');
  const Schema = mongoose.Schema;
  
  const ReportsSchema = new Schema({
    ReportFileData: Buffer,
    Cert_objid: { type: Schema.Types.ObjectId, ref: 'Certs' },
    Report_Type: String,
    Note: String,
    Dau_objID: { type: Schema.Types.ObjectId, ref: 'Dau' },
    Pau_objID: { type: Schema.Types.ObjectId, ref: 'Pau' }
  });
  
  module.exports = Reports = mongoose.model('Reports', ReportsSchema);
  </code></pre>
  
  <p>I use the following code to create the pdf file and save it. I didn't include the docDefinition as it's producing the correct file if it's saved directly to the server.</p>
  
  <pre><code>const PdfPrinter = require('pdfmake/src/printer');
  const path = require('path');
  const moment = require('moment');
  
  const Reports = require('../../models/Reports');  // Mongoose Schema
  
  const createFAReport = data =&gt; {
      docDefinition...
  
  createPdfBinary(docDefinition, binary =&gt; {
    const rpt = new Reports({
      ReportFileData: binary,
      Cert_objid: data._id,
      Report_Type: 'Water Use Report',
      Note: 'Testing 123'
    });
  
    rpt.save(err =&gt; {
      if (err) throw err;
      });
  });
  
  const createPdfBinary = (pdfDoc, callback) =&gt; {
    const fonts = {
      Roboto: {
      normal: path.join(__dirname, '../../', '/fonts/Roboto-Regular.ttf'),
      bold: path.join(__dirname, '../../', '/fonts/Roboto-Medium.ttf'),
      italics: path.join(__dirname, '../../', '/fonts/Roboto-Italic.ttf'),
      bolditalics: path.join(__dirname, '../../', '/fonts/Roboto-MediumItalic.ttf')
      }
    };
  
    const printer = new PdfPrinter(fonts);
    const doc = printer.createPdfKitDocument(pdfDoc);
    const chunks = [];
    let result;
  
    doc.on('data', function(chunk) {
      chunks.push(chunk);
    });
    doc.on('end', function() {
      result = Buffer.concat(chunks);
      callback('data:application/pdf;base64,' + result.toString('base64'));
    });
    doc.end();
  };
  </code></pre>
  
  <p>To then retrieve the encoded document from MongoDB and write it to a local file for testing I used the following code (please note that the aggregate is to get some associated fields required to retrieve the correct report):</p>
  
  <pre><code>router.get('/getReport', passport.authenticate('jwt', { session: false }), (req, res) =&gt; {
    Certs.aggregate([
      {
        $match: {
          Cert_ID: '1578'
        }
      },
      {
        $lookup: {
          from: 'reports',
          localField: '_id',
          foreignField: 'Cert_objid',
          as: 'rpt'
        }
      },
      {
        $unwind: {
          path: '$rpt',
          includeArrayIndex: '&lt;&lt;string&gt;&gt;',
          preserveNullAndEmptyArrays: false
        }
      }
    ]).then(result =&gt; {
      result.map(rslt =&gt; {
        console.log(rslt.Cert_ID);
        res.json({ msg: 'Got the report.' });
  
        const fullfilePath = path.join(__dirname, '../../', '/public/pdffiles/', `1578.pdf`
        );
  
        fs.writeFile(fullfilePath, rslt.rpt.ReportFileData, 'base64', () =&gt; {
          console.log('File Saved.');
         });
       });
     });
   });
  </code></pre>
  
  <p>Everything seems to work fine, except when I open the file I get an error that the file corrupted. I'm wondering if saving it to "base64" is a problem or is the datatype for MongoDB a problem. The data type is buffer so would you retrieve it as a buffer instead? Any help would be appreciated.</p>