【问题标题】:File upload with filestreams and Firebase cloud functions + cloud storage使用文件流和 Firebase 云功能 + 云存储上传文件
【发布时间】:2018-11-17 14:24:18
【问题描述】:

我为使用 Firebase 云函数上传 QR 文件编写了以下代码

const functions = require('firebase-functions');
const qrcode = require('qrcode')
const admin = require('firebase-admin');
const spawn = require('child-process-promise').spawn;
const serviceAccount = require("./secret.json");
const gcs = require('@google-cloud/storage')();

admin.initializeApp(functions.config({
  credential: admin.credential.cert(serviceAccount),
  storageBucket: "https://SECRET.firebaseio.com"
}));


exports.qrcode = functions.https.onRequest((req, res) => {
  const storage = admin.storage().bucket();
  const dummyFile = storage.file('dummy.png')
  new Promise ((resolve, reject) => qrcode.toFileStream(
    dummyFile.createWriteStream()
      .on('finish', resolve)
      .on('error', reject),
    'DummyQR'))
    .then(console.log("success")) //Doing stuff here later
    .catch(console.log)
  res.send("<script>window.close();</script>")
});

根据文档,我应该能够通过简单地调用 admin.storage().bucket(); (https://firebase.google.com/docs/storage/admin/start) 连接到存储桶,但是我收到以下错误:

Error: Error occurred while parsing your function triggers.

Error: Bucket name not specified or invalid. Specify a valid bucket name via the storageBucket option when initializing the app, or specify the bucket name explicitly when calling the getBucket() method.

所以我被卡住了,不知道如何继续。如果我尝试手动输入存储桶 admin.storage().bucket("https://SECRET.firebaseio.com"); 我会收到错误消息

{ ApiError: Not Found
    at Object.parseHttpRespBody (/user_code/node_modules/firebase-admin/node_modules/@google-cloud/storage/node_modules/@google-cloud/common/src/util.js:193:30)
    at Object.handleResp (/user_code/node_modules/firebase-admin/node_modules/@google-cloud/storage/node_modules/@google-cloud/common/src/util.js:131:18)
    at /user_code/node_modules/firebase-admin/node_modules/@google-cloud/storage/node_modules/@google-cloud/common/src/util.js:496:12
    at Request.onResponse [as _callback] (/user_code/node_modules/firebase-admin/node_modules/retry-request/index.js:195:7)
    at Request.self.callback (/user_code/node_modules/firebase-admin/node_modules/request/request.js:185:22)
    at emitTwo (events.js:106:13)
    at Request.emit (events.js:191:7)
    at Request.<anonymous> (/user_code/node_modules/firebase-admin/node_modules/request/request.js:1157:10)
    at emitOne (events.js:96:13)
    at Request.emit (events.js:188:7)
  code: 404,
  errors: [ { domain: 'global', reason: 'notFound', message: 'Not Found' } ],
  response: undefined,
  message: 'Not Found' }

【问题讨论】:

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


    【解决方案1】:

    您似乎没有正确初始化管理 SDK。只需调用不带参数的 initializeApp 即可获得所有正确的默认值:

    admin.initializeApp();
    

    这将使用 Cloud Functions 为您的项目提供的默认服务帐号。此帐户有权执行您在函数中需要执行的大部分操作,而无需任何额外配置。

    【讨论】:

    • 正确,但我确实需要添加 storageBucket,如下所示:admin.initializeApp({ credential: admin.credential.cert(serviceAccount), storageBucket: "https://XXX.firebaseio.com" });
    • 如果您只是访问项目的默认存储桶,则不需要添加存储桶。
    • 奇怪,我试过了,但我得到了和以前一样的错误
    • 我一直在编写通过 admin SDK 使用 Cloud Storage 的函数,而且我从来不需要配置任何东西。一个例外是您需要使用服务帐户进行初始化才能调用 getSignedUrl。
    • 好吧,我尝试了第二次,这次它只与admin.initializeApp(); 合作。也许 firebase 功能没有正确刷新。感谢您的帮助!
    【解决方案2】:

    我遇到了同样的问题。我刚刚在初始化应用程序时添加了 storageBucket 名称,如果您使用的是 getSignedUrl 方法,则需要包含一个服务帐户,否则该 url 会在一周后过期(就像我的情况一样)。

    const serviceAccount = require('/your/service/account/key/path');
    admin.initializeApp({
        credential: admin.credential.cert(serviceAccount),
        storageBucket: "your-storage-bucket-name.appspot.com",
    });
    

    别忘了用

    更新你的 firebase 函数
    firebase deploy --only functions
    

    在命令行上

    2020 年 4 月 6 日更新

    签名的网址实际上会在 7 天后过期。如果您需要更多时间的 URL,您应该阅读此 answer 和此 thread

    【讨论】:

    • 这应该是接受的答案,或者接受的答案应该明确表明您应该以其他方式设置您的凭据。
    • @SpencerWilliams 同样,您应该了解 Cloud Functions 为您的项目提供的默认服务帐户的行为。
    • 是的,这对我有用,我添加 storageBucket: "bucket name" 并且它可以工作
    【解决方案3】:

    在我的情况下,它与this one 的问题类似(在使用 firebase-admin 初始化应用程序时,如果不指定 storageBucket 就无法使用云存储)。

    我有以下设置:

    const admin = require("firebase-admin")
    admin.initializeApp()
    
    export * from "./api/api"
    export * from "./cron/cronJobs"
    export * from "./posts/postsCloudFunctions"
    

    改成:

    const admin = require("firebase-admin")
    
    export * from "./api/api"
    export * from "./cron/cronJobs"
    export * from "./posts/postsCloudFunctions"
    
    admin.initializeApp()
    

    问题似乎是在访问存储桶之前没有调用 initializeApp()。

    【讨论】:

      【解决方案4】:

      我在将图像上传到 Firebase 存储时遇到了同样的问题:

      错误:未指定存储桶名称或无效。初始化应用时通过 storageBucket 选项指定一个有效的桶名,或者在调用 getBucket() 方法时显式指定桶名。 ndlers\users.js:130:8) 在 Busboy.emit (events.js:189:13) 在 Busboy.emit (E:\react-project\socialape-functions\functions\node_modules\busboy\lib\main.js:37:33) 在 E:\react-project\socialape-functions\functions\node_modules\busboy\lib\types\multipart.js:52:13 在 process._tickCallback (internal/process/next_tick.js:61:11)

      然后我将 storageBucket 添加到管理功能

      var admin = require("firebase-admin");
      var serviceAccount = require("your service account key file path);
      
      admin.initializeApp({
        credential: admin.credential.cert(serviceAccount),
        databaseURL: "https://your-app-1234.firebaseio.com",
        storageBucket: "your-storage-bucket-name given in firebase storage"
      });
      
      const db = admin.firestore();
      
      module.exports = { admin, db };
      

      将存储桶添加到管理功能后,它就可以工作了。

      【讨论】:

        【解决方案5】:

        你应该改变

        storageBucket:“firebase 存储中给出的您的存储桶名称”

        到

        storageBucket:“.appspot.com”。

        您可以找到如下图所示的 BUCKET_NAME:

        【讨论】:

          猜你喜欢
          • 2017-12-21
          • 2019-08-08
          • 2017-12-19
          • 2021-03-07
          • 1970-01-01
          • 2021-10-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多