Solución:
También trabajé en esto y aquí debajo puede encontrar una muestra de la función en la nube que está creando un archivo PDF a partir de una plantilla HTML alojada en el almacenamiento de Firebase. Utiliza Hanldebars para aplicar algunos datos a la plantilla y luego cargarlos nuevamente en el almacenamiento de la base de fuego. Usé node-html-pdf aquí.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const pdf = require('html-pdf');
const gcs = require('@google-cloud/storage')({
projectId: '[YOUR PROJECT ID]',
//key generated from here https://console.firebase.google.com/project/_/settings/serviceaccounts/adminsdk?authuser=1
keyFilename: '[YOUR KEY]'
});
const handlebars = require('handlebars');
const path = require('path');
const os = require('os');
const fs = require('fs');
const bucket = gcs.bucket('[YOUR PROJECT ID].appspot.com');
admin.initializeApp(functions.config().firebase);
exports.helloWorld = functions.https.onRequest((request, response) => {
// data to apply to template file
const user = {
"date": new Date().toISOString(),
"firstname" : "Guillaume",
};
const options = {
"format": 'A4',
"orientation": "portrait"
};
const localTemplate = path.join(os.tmpdir(), 'localTemplate.html');
const localPDFFile = path.join(os.tmpdir(), 'localPDFFile.pdf');
bucket.file('template.html').download({ destination: localTemplate }).then(() => {
console.log("template downloaded locally");
const source = fs.readFileSync(localTemplate, 'utf8');
const html = handlebars.compile(source)(user);
console.log("template compiled with user data", html);
pdf.create(html, options).toFile(localPDFFile, function(err, res) {
if (err){
console.log(err);
return response.send("PDF creation error");
}
console.log("pdf created locally");
return bucket.upload(localPDFFile, { destination: user.name + '.pdf', metadata: { contentType: 'application/pdf'}}).then(() => {
response.send("PDF created and uploaded!");
}).catch(error => {
console.error(error);
response.send("PDF created and uploaded!");
});
});
});
});
Espero que esto ayude al próximo a hacer esto 🙂
Solo estoy trabajando en esto también, para guardar el PDF en el almacenamiento, funciona así
const myPdfFile = admin.storage().bucket().file('/test/Arbeitsvertrag.pdf');
const doc = new pdfkit();
const stream = doc.pipe(myPdfFile.createWriteStream());
doc.fontSize(25).text('Test 4 PDF!', 100, 100);
doc.end();
return res.status(200).send();
Supongo que debería esperar hasta que se cierre la transmisión y escuchar los errores y las cosas, pero este es el primer ejemplo de trabajo que pude hacer, ahora estoy trabajando en cómo obtener una imagen del almacenamiento en el PDF.
Probé la sugerencia de Guillaume y CASI me llevó allí. Desafortunadamente, Phantomjs estaba saliendo sin terminar.
Terminé resolviendo esto combinando la solución de Guillaume y https://phantomjscloud.com (y su biblioteca). Ahora todo funciona a la perfección.
Después de “plantilla compilada con datos de usuario”, sustituya lo siguiente:
const phantomJsCloud = require("phantomjscloud");
const browser = new phantomJsCloud.BrowserApi([YOURPHANTOMJSCLOUDAPIKEY]);
var pageRequest = { content: html, renderType: "pdf" };
// Send our HTML to PhantomJS to convert to PDF
return browser.requestSingle(pageRequest)
.then(function (userResponse) {
if (userResponse.statusCode != 200) {
console.log("invalid status code" + userResponse.statusCode);
} else {
console.log('Successfully generated PDF');
// Save the PDF locally
fs.writeFile(localPDFFile, userResponse.content.data, {
encoding: userResponse.content.encoding,
}, function (err) {
// Upload the file to our cloud bucket
return pdfBucket.upload(localPDFFile, { destination: 'desired-filename.pdf', metadata: { contentType: 'application/pdf'}}).then(() => {
console.log('bucket upload complete: '+ localPDFFile);
}).catch(error => {
console.error('bucket upload error:', error);
});
});
}
});