web-dev-qa-db-ja.com

index.htmlでFirebaseストレージに画像を表示する方法

Firebaseのストレージにいくつかの画像をアップロードした後、これらすべての画像をウェブサイトに表示する必要があります。 Firebaseからドキュメントを読みましたが、すべての画像を表示する正しい方法が見つかりません。だから、私の質問は、私のコードが単一の画像を表示するのに間違っているのはどこですか? Web上のすべての画像を同時に表示する方法(スタックオーバーフローに関する投稿を読んだので、すべての画像のURLを取得する必要がある場合があるため、サブの質問はすべての画像のURLを取得する方法です)?ちなみに、私のfirebaseのデータベースは空です。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>

    <script src="https://www.gstatic.com/firebasejs/3.2.1/firebase.js"></script>
    <script>
        var config =
        {
            apiKey: "AIzaSyCKtgPuXUUqoyiwEm5sU3Blqc-A9xtBFsI",
            authDomain: "cropped-images.firebaseapp.com",
            databaseURL: "https://cropped-images.firebaseio.com",
            storageBucket: "cropped-images.appspot.com",
        };

        firebase.initializeApp(config);
        var storage = firebase.storage();
        var storageRef = storage.ref();
        var tangRef = storageRef.child('images/Tang.png');

        tangRef.getDownloadURL().then(function(url) 
        {
            var test = url
            document.querySelector('img').src = test;
        }).catch(function(error) 
        {
            switch (error.code) 
            {
                case 'storage/object_not_found':
                    break;

                case 'storage/unauthorized':
                    break;

                case 'storage/canceled':
                    break;

                case 'storage/unknown':
                    break;
            }
        });

        var test = 'firebase_url';
        document.querySelector('img').src = test;



    </script>
    <img height="125" width="125"/>
    </body>
</html>

そして、これは私のFirebaseコンソールのストレージです。

firebase console's storage

4
OregonDuck

ファイルのダウンロードURLを取得するには、Firebaseサーバーへのラウンドトリップが必要です。この呼び出し(最近のインターネットのほとんどと同様)は非同期で発生します。これは、応答を待っている間にブラウザーをブロックすると、ユーザーエクスペリエンスが低下するためです。

コード内のフローを確認する最も簡単な方法は、いくつかのロギングステートメントを追加することです。

_console.log('Before requesting download URL');
tangRef.getDownloadURL().then(function(url) {
    console.log('Got download URL');
});
console.log('After requesting download URL');
_

コンソール出力は次のようになります。

ダウンロードURLをリクエストする前に

ダウンロードURLをリクエストした後

ダウンロードURLを取得しました

おそらく予想した順序ではなく、HTMLへのダウンロードURLをsetするコードは、then()コールバック内にある必要があることを意味します。

また、catch()コールバックで発生する可能性のあるエラーも無視しています。そこにロギングを追加する場合:

_tangRef.getDownloadURL().then(function(url)                             {
  document.querySelector('img').src = url;
}).catch(function(error) {
  console.error(error);
});
_

コードははるかに短いだけでなく、実際には問題が何であるかを正確に示しています。

GET https://firebasestorage.googleapis.com/v0/b/cropped-images.appspot.com/o/images%2FTang.png 403()

403は、画像を読み取る権限がないことを意味します。ほとんどの場合、ストレージバケットにはデフォルトのセキュリティルールがまだあります。つまり、認証されたユーザーのみがファイルにアクセスできます。これは、 ファイルの読み取り/書き込みに関するFirebase Storageのドキュメント (私の強調)の最初の青いメモに記載されています:

:デフォルトでは、FirebaseStorageバケットはファイルをアップロードするためにFirebase認証を必要とします。 Firebase Storageのセキュリティルールを変更 認証されていないアクセスを許可することができます。デフォルトのGoogleApp EngineアプリとFirebaseはこのバケットを共有するため、パブリックアクセスを設定すると、新しくアップロードされたAppEngineファイルもパブリックにアクセスできるようになる可能性があります。 認証を設定するときは、必ずストレージバケットへのアクセスを再度制限してください。

この場合、私は強調されたアプローチを採用し、画像のダウンロードURLを要求する前に、ユーザーに(匿名で)サインインするためのコードを追加しました。これにより、次の完全なコードスニペットが作成されます。

_var config = {
  apiKey: "AIzaSyCKtgPuXUUqoyiwEm5sU3Blqc-A9xtBFsI",
  authDomain: "cropped-images.firebaseapp.com",
  databaseURL: "https://cropped-images.firebaseio.com",
  storageBucket: "cropped-images.appspot.com",
};

firebase.initializeApp(config);
var storage = firebase.storage();
var storageRef = storage.ref();
var tangRef = storageRef.child('images/Tang.png');

// First we sign in the user anonymously
firebase.auth().signInAnonymously().then(function() {
  // Once the sign in completed, we get the download URL of the image
  tangRef.getDownloadURL().then(function(url)                             {
    // Once we have the download URL, we set it to our img element
    document.querySelector('img').src = url;

  }).catch(function(error) {
    // If anything goes wrong while getting the download URL, log the error
    console.error(error);
  });
});
_

完全に機能するjsbin: http://jsbin.com/kukifo/edit?html,js,console,output

12

受け入れられているものとは別の解決策は、デフォルトのルールを変更して、ユーザーにimagesというディレクトリからの読み取り専用権限を許可することです。

service firebase.storage {
  match /b/{bucket}/o {
    match /images/{fileName} {
      allow write: if request.auth != null;
      allow read;
    }

    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

この後、ディレクトリ内のファイルのダウンロードURLを取得し、token部分を削除します。

1
Eran H.