代码之家  ›  专栏  ›  技术社区  ›  JP Lew

如何访问节点上函数内部的Firebase存储。js服务器?

  •  11
  • JP Lew  · 技术社区  · 8 年前

    我正在运行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();
    

    然而,这对我来说并不适用,因为我使用的是管理SDK。我没有导入 firebase 图书馆。我尝试像这样访问存储:

    const fbStorage = admin.storage()
    

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

    node\u modules/firebase admin/lib/index。d、 ts

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

    node\u模块/firebase/索引。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') ,但这似乎有点迂回,我不确定我应该这样做。

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

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

    谢谢


    UDPATE(答案):

    多亏了雷诺的建议,我才知道我最初的尝试实际上是正确的。事实证明,您应该通过 admin.storage() . 接口定义确实不同,因为客户端SDK和管理(服务器端)SDK满足不同的需求。如果要包含类型定义,需要从“@谷歌云/存储”导入它们。

    下面是如何使用基于 the official docs :

    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 回复  |  直到 8 年前
        1
  •  4
  •   Renaud Tarnec    8 年前

    (我希望我正确理解了您的问题)下面是一个关于如何从云函数访问云存储以流式传输文件的示例:

        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