firebase功能在成功将映像保存到firebase云存储后获取下载URL

时间:2018-05-02 09:59:52

标签: typescript firebase google-cloud-storage firebase-admin

将图像保存到云存储后,我在firebase功能中获取下载URL时遇到问题。下面是我在firecript中的firebase http函数,用于将base64字符串保存到firebase云存储中的jpeg。当我记录结果时,它总是为空。我按照此链接获取下载URL  “Get Public URL from file uploaded with firebase-admin”。但它给了我以下错误:“ SigningError:身份和访问管理(IAM)API尚未在项目81673989436中使用之前或被禁用。 ”并且不能找到要遵循的简单示例。我的计划是在上传到云端存储后更新我的firestore表。

export const publishImage = functions.https.onRequest((req, res) => {
// Convert the base64 string back to an image to upload into the Google 
// Cloud Storage bucket
const base64EncodedImageString=req.body.image.replace(/^data:image\/jpeg;base64,/, "");
const mimeType = 'image/jpeg';
const randomFileName = crypto.randomBytes(16).toString('hex') + '.jpeg';    
const imageBuffer = new Buffer(base64EncodedImageString, 'base64');

const bucket = admin.storage().bucket();

// Upload the image to the bucket
const file = bucket.file('images/' + randomFileName);
file.save(imageBuffer, {
    metadata: { contentType: mimeType },
}).then(result => {
    console.log(result);
    file.makePublic();
    file.getSignedUrl({
        action: 'read',
        expires: '03-09-2491'
    }).then(urls => {
        console.log(urls[0]);
    })
});
return res.status(200).send("NOT WORKING");    
})

错误如firebase控制台中所示。即使有错误,我也可以将图像保存在存储中。

  

SigningError:权限iam.serviceAccounts.signBlob是在服务帐户projects/vmsystem-4aa54/serviceAccounts/vmsystem-4aa54@appspot.gserviceaccount.com上执行此操作所必需的。       at /user_code/node_modules/@google-cloud/storage/src/file.js:1715:16       在Request._callback(/user_code/node_modules/@google-cloud/storage/node_modules/google-auto-auth/index.js:356:9)       在Request.self.callback(/user_code/node_modules/@google-cloud/storage/node_modules/request/request.js:186:22)       在emitTwo(events.js:106:13)       在Request.emit(events.js:191:7)       在请求。 (/user_code/node_modules/@google-cloud/storage/node_modules/request/request.js:1163:10)       在emitOne(events.js:96:13)       在Request.emit(events.js:188:7)       在IncomingMessage。 (/user_code/node_modules/@google-cloud/storage/node_modules/request/request.js:1085:12)       在IncomingMessage.g(events.js:292:16)

我如何获得下载网址?

我感到困惑。现在,我在更改后坚持更新功能。 以下是我对admin的初始化。

 import * as admin from 'firebase-admin';
 const serviceAccount = require('./../service_account.json');

 try {   
 // admin.initializeApp(functions.config().firebase); // initial
 admin.initializeApp({
     credential: admin.credential.cert(serviceAccount),
     databaseURL: "https://vmsystem-4aa54.firebaseio.com"
 });
 } catch(e) {}
 import * as simpletest from './simpletest';
 export const testsomething = simpletest.helloWorld;

first

second

third

fourth

2 个答案:

答案 0 :(得分:5)

您未在此处显示所有代码(例如,您如何初始化Firebase Admin SDK以创建admin)。所以我假设您使用项目默认凭据来初始化它:

import * as admin from 'firebase-admin'
admin.initializeApp()

这不足以在进入管理SDK以使用云存储API时能够使用getSignedUrl。如果要使用getSignedUrl,则需要提供在控制台中创建的专用服务帐户的凭据。

假设您将这些凭据放在函数文件夹中名为yourServiceAccount.json的文件中,您应该使用以下凭据初始化admin SDK:

import * as serviceAccount from 'yourServiceAccount.json';
const adminConfig = JSON.parse(process.env.FIREBASE_CONFIG)
adminConfig.credential = admin.credential.cert(<any>serviceAccount)
admin.initializeApp(adminConfig);

请注意,这只是从FIREBASE_CONFIG获取默认项目配置并将服务帐户添加到它们。

为了获取JSON文件的导入,您还需要一个文件(名为typings.d.ts):

declare module "*.json" {
  const value: any;
  export default value;
}

答案 1 :(得分:0)

谢谢@Doug Stevenson。我相信我找到了答案。

  1. 我通过重新创建新项目来解决部署错误。

  2. 我将初始化更改为下面的代码以解决未处理的拒绝问题。转到firebase项目的Project Settings下的Service Acccounts,并在firebase admin sdk下生成新的私钥。

    const serviceAccount = require('./path/to/serviceaccount.json');
    admin.initializeApp({
      credential: admin.credential.cert(serviceAccount),
      databaseURL: '<ur database url>', // check it under service accounts
      storageBucket: '<ur storage bucket url>' //check it in script snippet require to add to your website.
    });