如何访问 Node.js 服务器上 Functions 内的 Firebase 存储?

Posted

技术标签:

【中文标题】如何访问 Node.js 服务器上 Functions 内的 Firebase 存储?【英文标题】:How do I access Firebase Storage inside of Functions on Node.js server? 【发布时间】:2018-08-19 11:31:49 【问题描述】:

我正在运行一个 Firebase Functions 实例,如下所示:

import * as functions from 'firebase-functions'
import * as express from 'express'
import * as admin from 'firebase-admin'
import  MyApi  from './server'

admin.initializeApp(functions.config().firebase)

const firebaseDb: admin.database.Database = admin.database()

const app: express.Application = MyApi.bootstrap(firebaseDb).app

export const myApp = functions.https.onRequest(app)

我的实时数据库一切正常,但我无法正确集成存储。根据the docs,我需要这样设置:

var config = 
  apiKey: '<your-api-key>',
  authDomain: '<your-auth-domain>',
  databaseURL: '<your-database-url>',
  storageBucket: '<your-storage-bucket>'
;
firebase.initializeApp(config);

// Get a reference to the storage service, which is used to create references in your storage bucket
var storage = firebase.storage();
var storageRef = storage.ref();

但这对我不起作用,因为我使用的是 Admin SDK。我根本没有导入firebase 库。我尝试像这样访问存储:

const fbStorage = admin.storage()

这感觉不对。 Admin 存储方式的接口与 Firebase 客户端 SDK 的接口完全不同:

node_modules/firebase-admin/lib/index.d.ts

declare namespace admin.storage 
  interface Storage 
    app: admin.app.App;
    bucket(name?: string): Bucket;
  

node_modules/firebase/index.d.ts

declare namespace firebase.storage 
  interface Storage 
    app: firebase.app.App;
    maxOperationRetryTime: number;
    maxUploadRetryTime: number;
    ref(path?: string): firebase.storage.Reference;
    refFromURL(url: string): firebase.storage.Reference;
    setMaxOperationRetryTime(time: number): any;
    setMaxUploadRetryTime(time: number): any;
  

值得注意的是,管理存储界面缺少ref()ref().put() 方法,因此没有任何处理上传文件的文档适用。我可以通过admin.storage().bucket().file('path/to/file.jpg') 访问我的文件,但这似乎相当迂回,我不确定我是否应该这样做。

作为一种解决方法,我尝试在 admin.initializeApp() 之上初始化一个非管理员 Firebase 应用程序 (firebase.initializeApp(config))。但是当我尝试启动给出致命错误database: Firebase: Firebase service named 'database' already registered (app/duplicate-service).的函数时@

现在我制作了一个单独的应用程序,并尝试将存储功能委托给该辅助应用程序。有没有更好的办法?

谢谢。


UDPATE(回答):

感谢 Renaud 的建议,我了解到我最初的尝试实际上是正确的。原来你应该通过admin.storage() 访问你的存储实例。接口定义确实不同,因为客户端 SDK 和管理(服务器端)SDK 满足不同的需求。如果要包含类型定义,则需要从“@google-cloud/storage”导入它们。

下面是一个基于the official docs的Bucket API使用示例:

import  Bucket  from '@google-cloud/storage'

const filename = 'path/to/myfile.mp3'

const bucket: Bucket = admin.storage().bucket()

bucket
  .upload(filename, 
    destination: 'audio/music/myfile.mp3',
  )
  .then(() => 
    console.log(`$filename uploaded to $bucket.name.`)
  )
  .catch(err => 
    console.error('ERROR:', err)
  )

【问题讨论】:

【参考方案1】:

(希望我正确理解了您的问题)以下是有关如何从云功能访问云存储以流式传输文件的示例:

    const config = 
        projectId: '.....',
        keyFilename: './......json'
    ;
    const storage = require('@google-cloud/storage')(config);
    const yourStorageBucket = 'xyz.appspot.com';


    const bucket = storage.bucket(yourStorageBucket);

    const file = bucket.file(filename);
    const stream = file.createWriteStream(resumable: false);
    ....

您可以在以下位置查看更多详细信息: https://cloud.google.com/nodejs/getting-started/using-cloud-storage#uploading_to_cloud_storage 和 https://firebase.google.com/docs/storage/extend-with-functions

【讨论】:

哦,太好了,我会尝试一下,稍后确认它是否有效,感谢您的链接。我想从服务器访问存储与从客户端访问完全不同。 确实如此。不要犹豫,寻求进一步的帮助。 它现在运行良好。由于我使用的是 Firebase,所有配置都是通过 firebase-admin 库自动完成的,所以我可以跳过这一步。不过,您的回答为我指明了正确的方向。谢谢! @RenaudTarnec 如何使用 NodeJS 读取已存储在 Storage 中的文件? @Learn2Code 看看cloud.google.com/nodejs/docs/reference/storage/2.5.x/File。如果您需要更多帮助或遇到问题,可以提出新问题。

以上是关于如何访问 Node.js 服务器上 Functions 内的 Firebase 存储?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过公共 IP 地址访问我的 node.js 服务器?

node.js - 请求 - 如何“emitter.setMaxListeners()”?

如何在 heroku 上远程调试 node.js 应用程序?

Chokidar (Node.js) 的效率如何?

如何在生产服务器上部署 Node.js 应用

如何从 Node.js 访问、检索、存储和删除文件到远程文件服务器?