title: How to download file from Cloud Storage [Firebase Hosting]
body: <p>I would like to make a web app using Firebase Hosting.</p>
  
  <ol>
  <li>make audio file using Cloud text to speech API</li>
  <li>upload that audio file to Cloud Storage</li>
  <li>download that audio file from Cloud Storage to a web browser</li>
  </ol>
  
  <p>I passed step 1 and 2, but have a trouble with step 3.
  I followed this turorial.</p>
  
  <p><a href="https://firebase.google.com/docs/storage/web/download-files" rel="nofollow noreferrer">https://firebase.google.com/docs/storage/web/download-files</a></p>
  
  <p>I deployed my Firebase project and tested my app. I could upload audio file to Cloud Storage, but I couldn't download it. I looked at browser's console, but I couldn't find any error message. There was no message in browser's console.</p>
  
  <p>Could you give me any advice? Thank you in advance.</p>
  
  <p>This is my main.js</p>
  
  <pre><code>'use strict';
  
  // Saves a new message on the Cloud Firestore.
  function saveMessage() {
    // Add a new message entry to the Firebase database.
    return firebase.firestore().collection('messages').add({
      text: messageInputElement.value,
      timestamp: firebase.firestore.FieldValue.serverTimestamp()
    }).catch(function(error) {
      console.error('Error writing new message to Firebase Database', error);
    });
  }
  
  // Checks that the Firebase SDK has been correctly setup and configured.
  function checkSetup() {
    if (!window.firebase || !(firebase.app instanceof Function) || !firebase.app().options) {
      window.alert('You have not configured and imported the Firebase SDK. ' +
          'Make sure you go through the codelab setup instructions and make ' +
          'sure you are running the codelab using `firebase serve`');
    }
  }
  
  // Checks that Firebase has been imported.
  checkSetup();
  
  // Shortcuts to DOM Elements.
  var messageInputElement = document.getElementById('text');
  var submitButtonElement = document.getElementById('download');
  
  // Saves message on form submit.
  submitButtonElement.addEventListener('click', saveMessage);
  
  
  // Create a reference from a Google Cloud Storage URI
  var storage = firebase.storage();
  var gsReference = storage.refFromURL('gs://advan********8.appspot.com/audio/sub.mp3')
  gsReference.getDownloadURL().then(function(url) {
    // This can be downloaded directly:
    var xhr = new XMLHttpRequest();
    xhr.responseType = 'blob';
    xhr.onload = function(event) {
      var blob = xhr.response;
    };
    xhr.open('GET', url);
    xhr.send();
  
  }).catch(function(error) {
    // A full list of error codes is available at
    // https://firebase.google.com/docs/storage/web/handle-errors
    switch (error.code) {
      case 'storage/object-not-found':
        console.log('storage/object-not-found')
        break;
  
      case 'storage/unauthorized':
        console.log('storage/unauthorized')
        break;
  
      case 'storage/canceled':
        console.log('storage/canceled')
        break;
  
      case 'storage/unknown':
        console.log('storage/unknown')
        break;
    }  
  });
  </code></pre>
  
  <p>This is index.js (Cloud Functions)</p>
  
  <pre><code>const functions = require('firebase-functions');
  var admin = require("firebase-admin");
  admin.initializeApp();
  const textToSpeech = require('@google-cloud/text-to-speech');
  
  exports.myFunction = functions.firestore
    .document('messages/{id}')
    .onCreate((change, context) =&gt; {
          const client = new textToSpeech.TextToSpeechClient();
          async function quickStart() {
  
              // The text to synthesize
              const text = 'Hello world';
  
              // Construct the request
              const request = {
                  input: {text: text},
                  // Select the language and SSML voice gender (optional)
                  voice: {languageCode: 'en-US', ssmlGender: 'NEUTRAL'},
                  // select the type of audio encoding
                  audioConfig: {audioEncoding: 'MP3'},
              };
  
  
              var bucket = admin.storage().bucket('adva********.appspot.com');
              var file = bucket.file('audio/sub.mp3')
              // Create the file metadata
              var metadata = {
                  contentType: 'audio/mpeg'
              };
  
              // Performs the text-to-speech request
              const [response] = await client.synthesizeSpeech(request);
              return await file.save(response.audioContent, metadata)
              .then(() =&gt; {
                console.log("File written to Firebase Storage.")
                return;
              })
              .catch((error) =&gt; {
                console.error(error);
              });
  
          }
          quickStart();
      });
  </code></pre>
  
  <p>This is index.html</p>
  
  <pre><code>&lt;!--./advance/index.html--&gt;
  &lt;!doctype html&gt;
  &lt;html lang="ja"&gt;
     &lt;head&gt;
        &lt;meta name="robots" content="noindex"&gt;
  
        &lt;title&gt;音読アプリ アドバンス&lt;/title&gt;
        &lt;link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"&gt;
        &lt;meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"&gt;
        &lt;link href="https://fonts.googleapis.com/css?family=M+PLUS+Rounded+1c&amp;display=swap" rel="stylesheet"&gt;
  
        &lt;style&gt; 
              #text {width: 100%; height: 300px; font-family: 'M PLUS Rounded 1c', sans-serif; font-size: 22px;}
  
              #download {font-family: 'M PLUS Rounded 1c', sans-serif; font-size: 28px;}
  
        &lt;/style&gt;
     &lt;/head&gt;
  
     &lt;body&gt;
        &lt;textarea id="text" class="form-control" name="text" placeholder="ここに英文を入力してください。" maxlength="3000" minlength="1"&gt;&lt;/textarea&gt;
        &lt;br&gt;
        &lt;div style="text-align:center"&gt;
          &lt;input id="download" class="btn btn-primary" type="submit" value="音声をダウンロード"&gt;
        &lt;/div&gt;
  
        &lt;script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"&gt;&lt;/script&gt;
        &lt;script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"&gt;&lt;/script&gt;
        &lt;script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"&gt;&lt;/script&gt;
  
        &lt;!-- Import and configure the Firebase SDK --&gt;
        &lt;!-- These scripts are made available when the app is served or deployed on Firebase Hosting --&gt;
        &lt;!-- If you do not want to serve/host your project using Firebase Hosting see https://firebase.google.com/docs/web/setup --&gt;
        &lt;script src="/__/firebase/7.14.3/firebase-app.js"&gt;&lt;/script&gt;
        &lt;script src="/__/firebase/7.14.3/firebase-auth.js"&gt;&lt;/script&gt;
        &lt;script src="/__/firebase/7.14.3/firebase-storage.js"&gt;&lt;/script&gt;
        &lt;script src="/__/firebase/7.14.3/firebase-messaging.js"&gt;&lt;/script&gt;
        &lt;script src="/__/firebase/7.14.3/firebase-firestore.js"&gt;&lt;/script&gt;
        &lt;script src="/__/firebase/7.14.3/firebase-performance.js"&gt;&lt;/script&gt;
        &lt;script src="/__/firebase/7.14.3/firebase-functions.js"&gt;&lt;/script&gt;
        &lt;script src="/__/firebase/init.js"&gt;&lt;/script&gt;
  
        &lt;script src="scripts/main.js"&gt;&lt;/script&gt;
     &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>browser's developer tool's Network tab
  <a href="https://i.stack.imgur.com/62iZZ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/62iZZ.png" alt="xhr"></a></p>