web-dev-qa-db-ja.com

Node.jsサーバーのFunctions内のFirebaseStorageにアクセスするにはどうすればよいですか?

私は次のようにFirebaseFunctionsインスタンスを実行しています:

_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)
_

リアルタイムデータベースではすべて正常に機能しますが、ストレージを適切に統合するのに問題があります。 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')を介してファイルにアクセスできますが、それはかなり回りくどいようで、そうすることになっているのかわかりません。

回避策として、管理者以外のFirebaseアプリ(firebase.initializeApp(config))をadmin.initializeApp()の上に初期化しようとしました。しかし、致命的なエラーを与える関数を起動しようとするとdatabase: Firebase: Firebase service named 'database' already registered (app/duplicate-service).

現在、別のアプリを作成し、ストレージ機能をそのセカンダリアプリに委任しようとしています。もっと良い方法はありますか?

ありがとう。


UDPATE(ANSWER):

ルノーのアドバイスのおかげで、私の最初の試みは実際には正しいものであることがわかりました。 admin.storage()を介してストレージインスタンスにアクセスすることになっていることがわかりました。クライアント側のSDKと管理者(サーバー側)のSDKは異なるニーズに対応しているため、インターフェイスの定義は異なります。タイプ定義を含める場合は、「@ google-cloud/storage」からインポートする必要があります。

以下は、 公式ドキュメント に基づいたBucketAPIの使用方法のサンプルです。

_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)
  })
_
7
JP Lew

(私はあなたの質問を正しく理解したと思います)ファイルをストリーミングするためにクラウド関数からクラウドストレージにアクセスする方法の例を次に示します。

    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

3
Renaud Tarnec