Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Firebase功能,将同步/异步混乱转换为干净的ES6_Firebase_Callback_Ecmascript 6_Promise_Google Cloud Functions - Fatal编程技术网

Firebase功能,将同步/异步混乱转换为干净的ES6

Firebase功能,将同步/异步混乱转换为干净的ES6,firebase,callback,ecmascript-6,promise,google-cloud-functions,Firebase,Callback,Ecmascript 6,Promise,Google Cloud Functions,我确实编写了一个firebase函数,它可以根据请求处理PDF文件,对其进行一些操作,将其保存回存储器,并将哈希文件归档到数据库 我确实成功地让它工作了,但它完全是一团糟,因为我从来没有真正学会如何使用ES6之前的js回调。我对这一切都不熟悉,并且学会了如何使用箭头功能和承诺。但是在这里我需要使用纯javascript的包,并且它以某种方式工作,但是我真的需要清理这个sync/async混乱,以完成干净的错误处理,并在处理函数后向firebase返回一个承诺 我的功能还包括一些奇怪的文件处理,以

我确实编写了一个firebase函数,它可以根据请求处理PDF文件,对其进行一些操作,将其保存回存储器,并将哈希文件归档到数据库

我确实成功地让它工作了,但它完全是一团糟,因为我从来没有真正学会如何使用ES6之前的js回调。我对这一切都不熟悉,并且学会了如何使用箭头功能和承诺。但是在这里我需要使用纯javascript的包,并且它以某种方式工作,但是我真的需要清理这个sync/async混乱,以完成干净的错误处理,并在处理函数后向firebase返回一个承诺

我的功能还包括一些奇怪的文件处理,以便为pdf库准备好不同的文件: 例如,我创建一个二维码,将其保存到一个tmp文件中,使用另一个库从png中创建一个jpg,然后再次将其保存到tmp。如果我能做一些更聪明的事情,我愿意接受任何建议或暗示

链出现问题,因为函数在几毫秒内完成,而它仍在运行

我确实在我的代码中添加了一些注释,但我不知道如何将其更改为ES6,如果您能帮助我清理这一混乱局面,我将不胜感激

const hummus = require('hummus');
const request = require('request');
const fs = require('fs');
const sha1 = require('sha1');
const images = require("images");

exports.handleDocSignRequests = functions.database.ref('/user_writeable/docrequests/{uid}').onWrite(event => {
    var userReq = event.data.val();
    var userRef = event.data.ref;
    if (!userReq) return Promise.resolve();
    if (!userReq.docpath) return Promise.resolve();
    let uid = event.params.uid;
    let filename = userReq.docpath; // File to sign and hash

    return bucket.file(filename).getSignedUrl({  // getting downloadurl from Firebase Storage
        action: 'read'
    }).then(
        (downloadpath) => {
            downloadpath = downloadpath[0];
            //download pdf - how to turn this into a promise?
            download = function (uri, filename, callback) {
                request.head(uri, function (err, res, body) {
                    request(uri).pipe(fs.createWriteStream(filename)).on('close', callback);
                });
            };
            let pdfsourse = LOCAL_TMP_FOLDER + 'downloadedfile.pdf';
            return download(downloadpath, pdfsourse, function () { // download callback turn this into ES6
                console.log('download finished');
                let qrjpg = LOCAL_TMP_FOLDER + 'qrcode.jpg';
                var qrpng = LOCAL_TMP_FOLDER + 'qrcode.png';
                let qrurl = 'https://some.url/' + userReq.docid;
                let pdfdest = LOCAL_TMP_FOLDER + 'newpdf.pdf';
                let logfile = './hummus.log';

                QRCode.toFile(qrpng, qrurl, {  // how to make this a part of the "chain" and go on when finished
                    version: 4, type: "png", scale: 2, margin: 0
                }, function (err) {
                    if (err) throw err;
                    console.log('qr png ready');
                    images(qrpng).save(qrjpg, {operation: 100}); // save png as jpg
                    console.log('qr jpg ready');
                });


                // Doing stuff to PDF with HummusJs
                let pdfWriter = hummus.createWriterToModify(pdfsourse, {
                    modifiedFilePath: pdfdest,
                    log: logfile,
                    userPassword: 'user',
                    ownerPassword: 'owner',
                    userProtectionFlag: 4

                });
                let pdfReader = pdfWriter.getModifiedFileParser();
                let arialFont = pdfWriter.getFontForFile(ariallocal);
                let textOptions = {font: arialFont, size: 5, colorspace: 'gray', color: 0x00};

                for (let i = 0; i < pdfReader.getPagesCount(); ++i) {
                    let pageBox = pdfReader.parsePage(i).getMediaBox();
                    let pageModifier = new hummus.PDFPageModifier(pdfWriter, i, true);
                    let ctx = pageModifier.startContext().getContext();
                    ctx.writeText('Document saved', 5, 110, textOptions);
                    ctx.drawImage(5, 52, qrfile,
                        {
                            transformation: {
                                width: 40,
                                height: 40,
                                fit: 'always'
                            }
                        });
                    pageModifier.endContext().writePage();
                }
                pdfWriter.end();
                // How can I be sure PDF is done and written to tmp file? Or is this given by sync function?
                // Reading finished PDF from file again, to get base64 for hashing - is there a better way?
                let newpdf = fs.readFileSync(pdfdest);
                let base64pdf = newpdf.toString('base64');
                let hash = sha1(base64pdf);
                let signobj = {};
                signobj['hash'] = hash;
                // Check if document already in database, if not write hash to database,
                // upload finished pdf to original place and archive
                // and return remove request
                let sign_ref = docsign_ref.child(userReq.docid);
                return sign_ref.once('value').then(function (snap) {
                    if (!snap.val()) { //Document is new
                        let upload1 = bucket.upload(destcry, {destination: filename}).then
                        (suc => {
                            console.log('uploaded');
                        });
                        //
                        let upload2 = bucket.upload(destcry, {destination: 'signed/' + userReq.docid + '.pdf'}).then
                        (suc => {
                            console.log('uploaded');
                        });
                        return Promise.all([upload1, upload2]).then( // When both uploads are finished go on
                            (suc) => {
                                return sign_ref.set(signobj).then(
                                    (suc) => {
                                        // Remove Request and return Promise
                                        return userRef.remove();
                                    });

                            });
                    }
                    else {
                        //Document already in database, this should never happen, only for seq reasons
                        console.log('doc already in database);
                        return Promise.resolve();
                    }
                });
            });
        });
});
const hummus=require('hummus');
const request=require('request');
常数fs=要求('fs');
const sha1=需要('sha1');
常量图像=需要(“图像”);
exports.handleDocSignRequests=functions.database.ref('/user_writeable/docrequests/{uid}').onWrite(事件=>{
var userReq=event.data.val();
var userRef=event.data.ref;
if(!userReq)返回Promise.resolve();
如果(!userReq.docpath)返回Promise.resolve();
设uid=event.params.uid;
让filename=userReq.docpath;//要签名和散列的文件
返回bucket.file(filename).getSignedUrl({//正在从Firebase存储获取下载URL
行动:“阅读”
}).那么(
(下载路径)=>{
downloadpath=downloadpath[0];
//下载pdf-如何将此转化为承诺?
下载=函数(uri、文件名、回调){
head(uri,函数(err,res,body){
请求(uri).pipe(fs.createWriteStream(filename)).on('close',callback);
});
};
让pdfsourse=LOCAL_TMP_FOLDER+'downloaddedfile.pdf';
返回下载(downloadpath,pdfsourse,function(){//download callback将其转换为ES6
log(“下载完成”);
让qrjpg=LOCAL_TMP_FOLDER+'qrcode.jpg';
var qrpng=LOCAL_TMP_文件夹+'qrcode.png';
让我们来看看https://some.url/'+userReq.docid;
让pdfdest=LOCAL_TMP_FOLDER+'newpdf.pdf';
让logfile='./hummus.log';
toFile(qrpng,qrull,{//如何使其成为“链”的一部分,并在完成后继续
版本:4,类型:“png”,比例:2,边距:0
},函数(err){
如果(错误)抛出错误;
console.log('qr-png-ready');
图像(qrpng).save(qrjpg,{operation:100});//将png另存为jpg
控制台日志(“qr jpg就绪”);
});
//使用HummusJs制作PDF文档
让pdfWriter=hummus.createWriterToModify(pdfsourse{
修改路径:pdfdest,
日志:日志文件,
用户密码:“用户”,
ownerPassword:“所有者”,
userProtectionFlag:4
});
设pdfReader=pdfWriter.getModifiedFileParser();
让arialFont=pdfWriter.getFontForFile(ariallocal);
让text选项={font:arialFont,大小:5,颜色空间:'gray',颜色:0x00};
for(设i=0;i{
console.log('upload');
});
//
让upload2=bucket.upload(destcry,{destination:'signed/'+userReq.docid+'.pdf'}),然后
(suc=>{
console.log('upload');
});
返回Pr
handleDocSignRequests().then( .... );
const hummus = require('hummus');
const request = require('request');
const fs = require('fs');
const sha1 = require('sha1');
const images = require("images");

exports.handleDocSignRequests = functions.database.ref('/user_writeable/docrequests/{uid}').onWrite(event => {
    var userReq = event.data.val();
    var userRef = event.data.ref;
    if (!userReq) return Promise.resolve();
    if (!userReq.docpath) return Promise.resolve();
    let uid = event.params.uid;
    let filename = userReq.docpath; // File to sign and hash

    // *** Define these variables at this level, so they are accessible throughout
    //     the flattened promise-chain:
    let signobj = {};
    let sign_ref = docsign_ref.child(userReq.docid);

    return bucket.file(filename).getSignedUrl({  // getting downloadurl from Firebase Storage
        action: 'read'
    }).then((downloadpath) => {
        downloadpath = downloadpath[0];
        let pdfsourse = LOCAL_TMP_FOLDER + 'downloadedfile.pdf';
        // *** turned into promise:
        // *** return the promise to the main promise chain
        return new Promise(resolve => {
            request.head(downloadpath, function (err, res, body) {
                request(downloadpath)
                    .pipe(fs.createWriteStream(pdfsourse))
                    .on('close', resolve);
            });
        });
    }).then(function () {
        console.log('download finished');
        let qrjpg = LOCAL_TMP_FOLDER + 'qrcode.jpg';
        var qrpng = LOCAL_TMP_FOLDER + 'qrcode.png';
        let qrurl = 'https://some.url/' + userReq.docid;
        // *** Return a promise to make this a part of the "chain" and go on when finished
        return new Promise( (resolve, reject) => {
            QRCode.toFile(qrpng, qrurl, {  
                version: 4, type: "png", scale: 2, margin: 0
            }, function (err) {
                if (err) reject(err); // *** reject 
                console.log('qr png ready');
                images(qrpng).save(qrjpg, {operation: 100}); // save png as jpg
                console.log('qr jpg ready');
                resolve(); // *** resolve the promise now it's done
            });
        });
    }).then(function () {
        // Doing stuff to PDF with HummusJs
        let pdfdest = LOCAL_TMP_FOLDER + 'newpdf.pdf';
        let logfile = './hummus.log';
        let pdfWriter = hummus.createWriterToModify(pdfsourse, {
            modifiedFilePath: pdfdest,
            log: logfile,
            userPassword: 'user',
            ownerPassword: 'owner',
            userProtectionFlag: 4
        });
        let pdfReader = pdfWriter.getModifiedFileParser();
        let arialFont = pdfWriter.getFontForFile(ariallocal);
        let textOptions = {font: arialFont, size: 5, colorspace: 'gray', color: 0x00};

        for (let i = 0; i < pdfReader.getPagesCount(); ++i) {
            let pageBox = pdfReader.parsePage(i).getMediaBox();
            let pageModifier = new hummus.PDFPageModifier(pdfWriter, i, true);
            let ctx = pageModifier.startContext().getContext();
            ctx.writeText('Document saved', 5, 110, textOptions);
            ctx.drawImage(5, 52, qrfile, {
                transformation: {
                    width: 40,
                    height: 40,
                    fit: 'always'
                }
            });
            pageModifier.endContext().writePage();
        }
        pdfWriter.end();
        // How can I be sure PDF is done and written to tmp file? Or is this given by sync function?
        // Reading finished PDF from file again, to get base64 for hashing - is there a better way?
        let newpdf = fs.readFileSync(pdfdest);
        let base64pdf = newpdf.toString('base64');
        let hash = sha1(base64pdf);
        signobj['hash'] = hash;
        // Check if document already in database, if not write hash to database,
        // upload finished pdf to original place and archive
        // and return remove request
        // *** Only return the basic promise. Perform the `then` on the outer chain.
        return sign_ref.once('value');
    }).then(function (snap) {
        // *** Do simple case first:
        if (snap.val()) { 
            //Document already in database, this should never happen, only for seq reasons
            console.log('doc already in database);
            return Promise.resolve();
        } // *** No need for `else` here. The above `return` is enough
        //Document is new
        // *** use array to replace two blocks of very similar code
        let promises = [filename, 'signed/' + userReq.docid + '.pdf'].map(destination =>
            return bucket.upload(destcry, {destination}).then(suc => {
                console.log('uploaded');
            });
        });
        // *** Return the basic promise. Perform the `then` on the outer chain
        return Promise.all(promises);// Wait for both uploads to finish
    }).then( suc => {
        // *** I suppose this also has to run when not a new document....
        // *** Again: return the promise and perform the `then` on the outer chain
        return sign_ref.set(signobj);
    }).then( suc => {
        // Remove Request and return Promise
        return userRef.remove();
    });
});