将文件从 Firebase Cloud Functions 上传到 Cloud Storage

Tho*_*hoe 12 firebase google-cloud-functions firebase-storage

文件是太复杂了,我听不懂。它展示了如何将文件从 Cloud Storage 下载到 Cloud Functions,操作该文件,然后将新文件上传到 Cloud Storage。我只想查看将文件从 Cloud Functions 上传到 Cloud Storage 的基本、最低限度的说明。为什么这不起作用:

const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp();

exports.storage = functions.firestore.document('Test_Value').onUpdate((change, context) => {

  var metadata = {
    contentType: 'text',
  };

  admin.storage().ref().put( {'test': 'test'}, metadata)
  .then(function() {
    console.log("Document written.");
  })
  .catch(function(error) {
    console.error(error);
  })

});
Run Code Online (Sandbox Code Playgroud)

错误信息是admin.storage(...).ref is not a function。我猜这firebase-admin包括 Firestore 但不包括 Storage?而不是firebase-admin我应该使用@google-cloud/storage?为什么这不起作用:

const functions = require('firebase-functions');
const admin = require('firebase-admin');

const {Storage} = require('@google-cloud/storage')();
const storage = new Storage();

admin.initializeApp();

exports.storage = functions.firestore.document('Test_Value').onUpdate((change, context) => {

  storage.bucket().upload( {'test': 'test'} , {
    metadata: {
      contentType: 'text'
    }
  })

});
Run Code Online (Sandbox Code Playgroud)

我什至无法部署此代码,错误消息是

Error parsing triggers: Cannot find module './clone.js'
Run Code Online (Sandbox Code Playgroud)

显然缺少 npm 模块依赖项?但是模块没有被调用clone.js?我试过要求child-process-promise, path, os, 和fs; 没有修复丢失的clone.js错误。

为什么admin.initializeApp();缺少参数,当我的index.html文件中有:

firebase.initializeApp({
    apiKey: 'swordfish',
    authDomain: 'myapp.firebaseapp.com',
    databaseURL: "https://myapp.firebaseio.com",
    projectId: 'myapp',
    storageBucket: "myapp.appspot.com"
  });
Run Code Online (Sandbox Code Playgroud)

我看到的另一个问题:

npm list -g --depth=0       

/Users/TDK/.nvm/versions/node/v6.11.2/lib
??? child_process@1.0.2
??? UNMET PEER DEPENDENCY  error: ENOENT: no such file or directory, open '/Users/TDK/.nvm/versions/node/v6.11.2/lib/node_modules/firebase-admin/package.json
??? firebase-functions@2.1.0
??? firebase-tools@6.0.1
??? firestore-backup-restore@1.3.1
??? fs@0.0.2
??? npm@6.4.1
??? npm-check@5.9.0
??? protractor@5.4.1
??? request@2.88.0
??? watson-developer-cloud@3.13.0
Run Code Online (Sandbox Code Playgroud)

换句话说firebase-admin, 或 有问题Node 6.11.2。我应该使用 Node 版本管理器恢复到旧版本的 Node 吗?

Mar*_*ark 10

  1. 转到https://console.cloud.google.com/iam-admin/iam
  2. 单击您旁边的铅笔图标 App Engine default service account
  3. + ADD ANOTHER ROLE
  4. 添加 Cloud Functions Service Agent

在我的特定用例中,我需要将 base64 字符串解码为字节数组,然后使用它来保存图像。

    var serviceAccount = require("./../serviceAccountKey.json");

    import * as functions from 'firebase-functions';
    import * as admin from 'firebase-admin';    

    admin.initializeApp({
        projectId: serviceAccount.project_id, 
        credential: admin.credential.cert(serviceAccount),
        databaseURL: "https://your_project_id_here.firebaseio.com", //update this
        storageBucket: "your_bucket_name_here.appspot.com" //update this
      });

    function uploadProfileImage(imageBytes64Str: string): Promise<any> {

        const bucket = admin.storage().bucket()
        const imageBuffer = Buffer.from(imageBytes64Str, 'base64')
        const imageByteArray = new Uint8Array(imageBuffer);
        const file = bucket.file(`images/profile_photo.png`);
        const options = { resumable: false, metadata: { contentType: "image/jpg" } }

        //options may not be necessary
        return file.save(imageByteArray, options)
        .then(stuff => {
            return file.getSignedUrl({
                action: 'read',
                expires: '03-09-2500'
              })
        })
        .then(urls => {
            const url = urls[0];
            console.log(`Image url = ${url}`)
            return url
        })
        .catch(err => {
            console.log(`Unable to upload image ${err}`)
        })
    }
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样调用方法并链接调用。

    uploadProfileImage(image_bytes_here)
    .then(url => {
        //Do stuff with the url here        
    })
Run Code Online (Sandbox Code Playgroud)

注意:您必须使用服务帐户初始化 admin 并指定默认存储桶。如果您只是这样做,admin.initializeApp()那么您的图片网址将在 10 天后过期。

正确使用服务帐号的步骤。

  1. 转到服务帐户并生成私钥
  2. 将 JSON 文件放在您的函数文件夹中(在 src 和 node_modules 旁边)
  3. 转到存储并复制前面不包括“gs://”的 URL。初始化管理员时,将此用于存储桶 url。
  4. 使用上面的项目 ID 作为数据库 URL。


Ron*_*ton 6

有关如何在 Firebase Admin SDK 中使用云存储服务的更多详细信息,请参阅管理云存储 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' is an object defined in the @google-cloud/storage library.
// See https://googlecloudplatform.github.io/google-cloud-node/#/docs/storage/latest/storage/bucket
// for more details.
Run Code Online (Sandbox Code Playgroud)

关于上传对象,请参见云存储文档上传对象示例代码:

// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');

// Creates a client
const storage = new Storage();

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const bucketName = 'Name of a bucket, e.g. my-bucket';
// const filename = 'Local file to upload, e.g. ./local/path/to/file.txt';

// Uploads a local file to the bucket
await storage.bucket(bucketName).upload(filename, {
  // Support for HTTP requests made with `Accept-Encoding: gzip`
  gzip: true,
  metadata: {
    // Enable long-lived HTTP caching headers
    // Use only if the contents of the file will never change
    // (If the contents will change, use cacheControl: 'no-cache')
    cacheControl: 'public, max-age=31536000',
  },
});

console.log(`${filename} uploaded to ${bucketName}.`);
Run Code Online (Sandbox Code Playgroud)

  • 该代码创建一个存储桶,但不会将文件上传到存储。 (2认同)

Tho*_*hoe 4

我通过 Google Cloud Functions 将文件从硬盘上传到 Firebase Cloud Storage。首先,我找到了Google Cloud Functions bucket.upload的文档

    const functions = require('firebase-functions');
    const admin = require('firebase-admin');
    admin.initializeApp();
    
    exports.Storage = functions.firestore.document('Storage_Value').onUpdate((change, context) => {
    
      const {Storage} = require('@google-cloud/storage');
      const storage = new Storage();
      const bucket = storage.bucket('myapp.appspot.com');
    
      const options = {
        destination: 'Test_Folder/hello_world.dog'
      };
    
      bucket.upload('hello_world.ogg', options).then(function(data) {
        const file = data[0];
      });
    
      return 0;
    });
Run Code Online (Sandbox Code Playgroud)

前三行是 Cloud Functions 样板文件。下一行

    exports.Storage = functions.firestore.document('Storage_Value').onUpdate((change, context) => {
Run Code Online (Sandbox Code Playgroud)

创建云函数并设置触发器。接下来的三行更多的是 Google Cloud 样板。

其余代码hello_world.ogg在我的计算机硬盘驱动器上functions的项目目录文件夹中找到该文件,并将其上传到该目录,并将文件名更改为我的 Firebase Cloud Storage 中Test_Folder的名称。这会返回一个承诺,除非您想对文件执行其他操作,否则hello_world.dog下一行是不必要的。const file = data[0];

最后我们return 0;。该行除了阻止错误消息之外什么也不做

Function returned undefined, expected Promise or Value
Run Code Online (Sandbox Code Playgroud)