Javascript 使用 Node.js 将文件上传到 Firebase 存储

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39848132/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 22:57:55  来源:igfitidea点击:

Upload files to Firebase Storage using Node.js

javascriptnode.jsfirebasegcloudfirebase-storage

提问by Ionic? Biz?u

I'm trying to understand how to upload files in Firebase Storage, using Node.js. My first try was to use the Firebase library:

我试图了解如何使用 Node.js 在 Firebase 存储中上传文件。我的第一次尝试是使用 Firebase 库:

"use strict";

var firebase = require('firebase');

var config = {
    apiKey: "AIz...kBY",
    authDomain: "em....firebaseapp.com",
    databaseURL: "https://em....firebaseio.com",
    storageBucket: "em....appspot.com",
    messagingSenderId: "95...6"
};

firebase.initializeApp(config);

// Error: firebase.storage is undefined, so not a function
var storageRef = firebase.storage().ref();

var uploadTask = storageRef.child('images/octofez.png').put(file);

// Register three observers:
// 1. 'state_changed' observer, called any time the state changes
// 2. Error observer, called on failure
// 3. Completion observer, called on successful completion
uploadTask.on('state_changed', function(snapshot){
    ...
}, function(error) {
    console.error("Something nasty happened", error);
}, function() {
  var downloadURL = uploadTask.snapshot.downloadURL;
  console.log("Done. Enjoy.", downloadURL);
});

But it turns out that Firebase cannot upload files from the server side, as it clearly states in the docs:

但事实证明,Firebase 无法从服务器端上传文件,正如文档中明确指出的那样:

Firebase Storage is not included in the server side Firebase npm module. Instead, you can use the gcloud Node.js client.

$ npm install --save gcloud

In your code, you can access your Storage bucket using:

var gcloud = require('gcloud')({ ... }); var gcs = gcloud.storage();
var bucket = gcs.bucket('<your-firebase-storage-bucket>');

Firebase 存储不包含在服务器端 Firebase npm 模块中。相反,您可以使用 gcloud Node.js 客户端。

$ npm install --save gcloud

在您的代码中,您可以使用以下方式访问您的存储桶:

var gcloud = require('gcloud')({ ... }); var gcs = gcloud.storage();
var bucket = gcs.bucket('<your-firebase-storage-bucket>');
  • Can we use gcloudwithout having an account on Google Cloud Platform? How?

  • If not, how come that uploading files to Firebase Storage from the client side is possible?

  • Can't we just create a library that makes the same requests from the server side?

  • How is Firebase Storage connected with Google Cloud Platform at all? Why Firebase allows us to upload images only from the client side?

  • 我们可以在gcloud没有 Google Cloud Platform 帐户的情况下使用吗?如何?

  • 如果没有,为什么可以从客户端将文件上传到 Firebase 存储?

  • 我们不能创建一个从服务器端发出相同请求的库吗?

  • Firebase Storage 是如何与 Google Cloud Platform 连接的?为什么 Firebase 只允许我们从客户端上传图片?



My second try was to use the gcloudlibrary, like mentioned in the docs:

我的第二次尝试是使用该gcloud库,如文档中所述:

var gcloud = require("gcloud");

// The following environment variables are set by app.yaml when running on GAE,
// but will need to be manually set when running locally.
// The storage client is used to communicate with Google Cloud Storage
var storage = gcloud.storage({
  projectId: "em...",
  keyFilename: 'auth.json'
});

storage.createBucket('octocats', function(err, bucket) {

    // Error: 403, accountDisabled
    // The account for the specified project has been disabled.

    // Create a new blob in the bucket and upload the file data.
    var blob = bucket.file("octofez.png");
    var blobStream = blob.createWriteStream();

    blobStream.on('error', function (err) {
        console.error(err);
    });

    blobStream.on('finish', function () {
        var publicUrl = `https://storage.googleapis.com/${bucket.name}/${blob.name}`;
        console.log(publicUrl);
    });

    fs.createReadStream("octofez.png").pipe(blobStream);
});

采纳答案by Nicolas Garnier

When using the firebase library on a server you would typically authorize using a service accountas this will give you admin access to the Realtime database for instance. You can use the same Service Account's credentials file to authorize gcloud.

在服务器上使用 firebase 库时,您通常会使用服务帐户进行授权,因为这将授予您对实时数据库的管理员访问权限。您可以使用同一个服务帐号的凭据文件来授权 gcloud

By the way: A Firebase project is essentially also a Google Cloud Platform project, you can access your Firebase project on both https://console.firebase.google.comand https://console.cloud.google.comand https://console.developers.google.comYou can see your Project ID on the Firebase Console > Project Settingsor in the Cloud Console Dashboard

顺便说一句:Firebase 项目本质上也是一个 Google Cloud Platform 项目,您可以在https://console.firebase.google.comhttps://console.cloud.google.comhttps上访问您的 Firebase 项目: //console.developers.google.com您可以在Firebase 控制台 > 项目设置Cloud Console 控制面板中查看您的项目 ID

When using the gcloud SDK make sure that you use the (already existing) same bucket that Firebase Storage is using. You can find the bucket name in the Firebase web configobject or in the Firebase Storage tab. Basically your code should start like this:

使用 gcloud SDK 时,请确保使用 Firebase Storage 正在使用的(已经存在的)相同存储桶。您可以在 Firebase 网络config对象或 Firebase 存储选项卡中找到存储桶名称。基本上你的代码应该像这样开始:

var gcloud = require('gcloud');

var storage = gcloud.storage({
  projectId: '<projectID>',
  keyFilename: 'service-account-credentials.json'
});

var bucket = storage.bucket('<projectID>.appspot.com');

...

回答by Laurent

Firebase Storage is now supported by the admin SDK with NodeJS:

带有 NodeJS 的管理 SDK 现在支持 Firebase 存储:

https://firebase.google.com/docs/reference/admin/node/admin.storage

https://firebase.google.com/docs/reference/admin/node/admin.storage

// Get the Storage service for the default app
var defaultStorage = firebaseAdmin.storage();
var bucket = defaultStorage.bucket('bucketName');
...

回答by Madhav

Firebase Admin SDK allows you to directly access your Google Cloud Storage.

Firebase Admin SDK 允许您直接访问您的 Google Cloud Storage。

For more detail visit Introduction to the Admin Cloud Storage API

有关更多详细信息,请访问Admin Cloud Storage API 简介

var admin = require("firebase-admin");
var serviceAccount = require("path/to/serviceAccountKey.json");

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    storageBucket: "<BUCKET_NAME>.appspot.com"
});

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

bucket.upload('Local file to upload, e.g. ./local/path/to/file.txt')

回答by Rajesh Kumar Kanumetta

I hope It will useful for you. I uploaded one file from locally and then I added access Token using UUID after that I uploaded into firebase storage.There after I am generating download url. If we hitting that generate url it will automatically downloaded a file.

我希望它对你有用。我从本地上传了一个文件,然后我使用 UUID 添加了访问令牌,之后我上传到了 firebase 存储。在我生成下载 url 之后。如果我们点击该生成网址,它将自动下载一个文件。

    const keyFilename="./xxxxx.json"; //replace this with api key file
    const projectId = "xxxx" //replace with your project id
    const bucketName = "xx.xx.appspot.com"; //Add your bucket name
    var mime=require('mime-types');
    const { Storage } = require('@google-cloud/storage');
    const uuidv1 = require('uuid/v1');//this for unique id generation

   const gcs = new Storage({
    projectId: projectId,
    keyFilename: './xxxx.json'
     });
    const bucket = gcs.bucket(bucketName);

    const filePath = "./sample.odp";
    const remotePath = "/test/sample.odp";
    const fileMime = mime.lookup(filePath);

//we need to pass those parameters for this function
    var upload = (filePath, remoteFile, fileMime) => {

      let uuid = uuidv1();

      return bucket.upload(filePath, {
            destination: remoteFile,
            uploadType: "media",
            metadata: {
              contentType: fileMime,
              metadata: {
                firebaseStorageDownloadTokens: uuid
              }
            }
          })
          .then((data) => {

              let file = data[0];

              return Promise.resolve("https://firebasestorage.googleapis.com/v0/b/" + bucket.name + "/o/" + encodeURIComponent(file.name) + "?alt=media&token=" + uuid);
          });
    }
//This function is for generation download url    
 upload(filePath, remotePath, fileMime).then( downloadURL => {
        console.log(downloadURL);

      });

回答by Shubham Kanodia

Or you could simply polyfill XmlHttpRequestlike so -

或者你可以XmlHttpRequest像这样简单地填充-

const XMLHttpRequest = require("xhr2");
global.XMLHttpRequest = XMLHttpRequest

and import

和进口

require('firebase/storage');

That's it. All firebase.storage()methods should now work.

就是这样。所有firebase.storage()方法现在都应该有效。

回答by MrRhoads

Note that gcloud is deprecated, use google-cloud instead. You can find SERVICE_ACCOUNT_KEY_FILE_PATH at project settings->Service Accounts.

请注意,不推荐使用 gcloud,请改用 google-cloud。您可以在项目设置->服务帐户中找到 SERVICE_ACCOUNT_KEY_FILE_PATH。

var storage = require('@google-cloud/storage');

var gcs = storage({
    projectId: PROJECT_ID,
    keyFilename: SERVICE_ACCOUNT_KEY_FILE_PATH
  });

// Reference an existing bucket.
var bucket = gcs.bucket(PROJECT_ID + '.appspot.com');

...