使用Firebase功能获取上载到Firebase存储的pdf的签名下载URL

时间:2018-10-09 21:00:24

标签: firebase google-cloud-storage

在花了很多时间在Google上并花费了无数小时的文档阅读之后,我来这里是为了提出这个问题,因为我没有取得任何进步。

我正在尝试使用firebase函数将文件上传到Firebase存储,然后获取下载URL,以便在firebase函数完成时发回。

首先,我在firebase-admin的顶部包含了@google-cloud/storageindex.js。然后初始化它们。

const storage = require('@google-cloud/storage');
const functions = require('firebase-functions');
const admin = require("firebase-admin");

admin.initializeApp({
   credential: admin.credential.cert({ 
       // removed for security
       // This block was provided by Firebase Admin SDK 
       // under service accounts in settings of Firebase.
   }),
   databaseUrl: //removed for security,
   storageBucket: //removed for security
});

然后,最后,我创建Firebase数据库记录,生成PDF并将该文件存储在Firebase存储中的函数,然后应该向我返回一个有效网址以获取pdf。

exports.createInvoice = functions.https.onRequest((req, res) => {
    cors(req, res, () => {
        if(req.method == 'POST') {
            generateInvoiceNumber().then((number) => {
                req.body.number = number.number;
                req.body.created = admin.database.ServerValue.TIMESTAMP;
                var total = 0;
                var items = req.body.items;
                for (var i = items.length - 1; i >= 0; i--) {
                    total = total + (items[i].cost * items[i].qty);
                }
                req.body.total = total.toFixed(2);
                admin.database().ref('invoices').push(req.body).then(function(response){
                    var html = // removed for brevity;
                    var file = admin.storage().bucket().file('/tmp/invoice-'+number.number+'.pdf');
                    htmlPdf.create(html).toStream(function(err, stream){
                        stream.pipe(file.createWriteStream());
                        //stream.on('finish', function(){
                            const config = {
                                action: 'read',
                                expires: '03-09-2491',
                                contentType: 'application/pdf'
                            };
                            admin.storage().bucket().file('tmp/invoice-'+number.number+'.pdf').getSignedUrl(config).then(signedUrls => {
                                res.status(200).send(signedUrls);
                            })
                        //});
                    });
                });
            }).catch(error => {
                res.status(500).send(error);
            })
        } else {
            res.status(405).send('Method Not Allowed');
        }
    });
});

唯一无法正常工作的部分是函数结尾附近的返回URL。

admin.storage().bucket().file('tmp/invoice-'+number.number+'.pdf').getSignedUrl(config).then(signedUrls => {
  res.status(200).send(signedUrls);
});

当我尝试在浏览器中访问返回的URL时,出现以下错误。

The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.

1 个答案:

答案 0 :(得分:0)

好吧,我在做什么,因为我正在使用类似的东西,所以我发现您在元数据中寻找的键是mediaLink。这是我的代码示例。

                  admin.storage().bucket().file(`home/home-carousel/${filename}`).save(file, (data) => {
                if(!data){
                  res(admin.storage().bucket().file(`home/home-carousel/${filename}`).getMetadata().mediaLink)
                }
              } )

res()是您想要的部分!

编辑:getMetadata返回一个承诺,您必须解析该承诺才能获取元数据,如果不这样做,那么mediaLink将是未定义的。而且,有一些参数从promise返回,像数组一样访问它们,我提供了一个代码示例。

const saveLocation = storage.bucket('salesportal-8b7ef.appspot.com').file(`home/home-carousel/${webPFileName}`)
                  saveLocation.save(data, (stuff) => {
                    if(!stuff){
                      saveLocation.makePublic().then( () => {
                        saveLocation.getMetadata()
                        .then( (meta) => {
                          metadata = meta[0]
                            admin.firestore().collection("Pages").doc("home-carousel").set({ homeCarousel : {[`${filename}`] : { webPUrl : `${metadata.mediaLink}`}} }, {merge: true}).then( 
                              () => {
                                resolve()
                              })
                        })

                      })
                    }