Firebase Cloud Storage: resource: the server responded with a status of 403 ()

怎甘沉沦 提交于 2020-06-17 09:45:11

问题


I make a simple audio recording web app using Firebase Hosting. I would like to record audio on browser and upload it to Cloud Storage. When I deploy and access my app, I can record audio. However the app failed to upload the audio to Cloud Storage.

(I use Windows 10, Windows Subsystems for Linux, Debian 10.3 and Google Chrome browser. )

This is an error message in browser's console.

firebasestorage.googleapis.com/v0/b/ondoku-dc29c.appspot.com/o?name=audio%2Fspeech.wav:1 
Failed to load resource: the server responded with a status of 403 ()

This is a screenshot of browser's console.

I searched the Internet and found that an 403() error means that you do not have permission to upload to firebase storage.

However, I couldn't found the way to get permission.

Could you give me any advice? Thank you in advance.


This is my index.html.

<!doctype html>
<html lang="ja">
   <head>
      <meta name="robots" content="noindex">

      <title>音読アプリ アドバンス</title>
      <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
      <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
      <link href="https://fonts.googleapis.com/css?family=M+PLUS+Rounded+1c&display=swap" rel="stylesheet">
      <meta http-equiv="content-type" content="text/html; charset=utf-8" />


      <script src="https://www.WebRTC-Experiment.com/RecordRTC.js"></script>
   </head>

   <body>
      <div>
        <button id="start-recording" disabled>Start Recording</button>
        <button id="stop-recording" disabled>Stop Recording</button>
      </div>

      <script type="text/javascript">
          const startRecording = document.getElementById('start-recording');
          const stopRecording = document.getElementById('stop-recording');
          let recordAudio;
          startRecording.disabled = false;

          // on start button handler
          startRecording.onclick = function() {
              // recording started
              startRecording.disabled = true;

              // make use of HTML 5/WebRTC, JavaScript getUserMedia()
              // to capture the browser microphone stream
              navigator.getUserMedia({
                  audio: true
              }, function(stream) {
                      recordAudio = RecordRTC(stream, {
                      type: 'audio',
                      mimeType: 'audio/webm',
                      sampleRate: 44100, // this sampleRate should be the same in your server code

                      // MediaStreamRecorder, StereoAudioRecorder, WebAssemblyRecorder
                      // CanvasRecorder, GifRecorder, WhammyRecorder
                      recorderType: StereoAudioRecorder,

                      // Dialogflow / STT requires mono audio
                      numberOfAudioChannels: 1,

                      // get intervals based blobs
                      // value in milliseconds
                      // as you might not want to make detect calls every seconds
                      timeSlice: 4000,

                      // only for audio track
                      // audioBitsPerSecond: 128000,

                      // used by StereoAudioRecorder
                      // the range 22050 to 96000.
                      // let us force 16khz recording:
                      desiredSampRate: 16000
                  });

                  recordAudio.startRecording();
                  stopRecording.disabled = false;
              }, function(error) {
                  console.error(JSON.stringify(error));
              });
          };

          // on stop button handler
          stopRecording.onclick = function() {
              // recording stopped
              startRecording.disabled = false;
              stopRecording.disabled = true;

              // stop audio recorder
              recordAudio.stopRecording(function() {
                var blob = recordAudio.getBlob()

                // Create a root reference
                var storageRef = firebase.storage().ref();

                // Create the file metadata
                var metadata = {
                  contentType: 'audio/wav'
                };

                // Upload file and metadata to the object 'images/mountains.jpg'
                var uploadTask = storageRef.child('audio/speech.wav').put(blob, metadata);

                // Listen for state changes, errors, and completion of the upload.
                uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED, // or 'state_changed'
                  function(snapshot) {
                    // Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
                    var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
                    console.log('Upload is ' + progress + '% done');
                    switch (snapshot.state) {
                      case firebase.storage.TaskState.PAUSED: // or 'paused'
                        console.log('Upload is paused');
                        break;
                      case firebase.storage.TaskState.RUNNING: // or 'running'
                        console.log('Upload is running');
                        break;
                    }
                  }, 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/unauthorized':
                      // User doesn't have permission to access the object
                      break;

                    case 'storage/canceled':
                      // User canceled the upload
                      break;


                    case 'storage/unknown':
                      // Unknown error occurred, inspect error.serverResponse
                      break;
                  }
                }, function() {
                  // Upload completed successfully, now we can get the download URL
                  uploadTask.snapshot.ref.getDownloadURL().then(function(downloadURL) {
                    console.log('File available at', downloadURL);
                  });
                });                 
              });
            };
      </script>



      <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
      <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
      <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>

      <!-- Import and configure the Firebase SDK -->
      <!-- These scripts are made available when the app is served or deployed on Firebase Hosting -->
      <!-- If you do not want to serve/host your project using Firebase Hosting see https://firebase.google.com/docs/web/setup -->
      <script src="/__/firebase/7.14.3/firebase-app.js"></script>
      <script src="/__/firebase/7.14.3/firebase-auth.js"></script>
      <script src="/__/firebase/7.14.3/firebase-storage.js"></script>
      <script src="/__/firebase/7.14.3/firebase-messaging.js"></script>
      <script src="/__/firebase/7.14.3/firebase-firestore.js"></script>
      <script src="/__/firebase/7.14.3/firebase-performance.js"></script>
      <script src="/__/firebase/7.14.3/firebase-functions.js"></script>
      <script src="/__/firebase/init.js"></script>

      <!-- <script src="scripts/main.js"></script> -->
   </body>
</html>

回答1:


For you to get the permissions correctly, you need to check your Firebase Storage Security Rules. Configuring them correctly, will provide the access and permissions needed for the audios to be upload to the storage. By default, the rules will ask you to be authenticated, so you need to check to confirm. This way, you can either change your application to have authentication (best option) or the rules.

You can change the rules by accessing the Firebase Console and accessing the tab Rules. If you check the rules and they are similar or equal to the one below, it's confirming that you will need to be authenticated to write in the database, which is causing the error you are seeing.

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

For tests only, you can change the rules to the below one, so you can bypass the error, while you don't fix the authentication. Please, keep in mind that this will open the accessing to read and write to not authenticated users, so it should be used only for testing.

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth == null;
    }
  }
}

Let me know if the information helped you!



来源:https://stackoverflow.com/questions/61927039/firebase-cloud-storage-resource-the-server-responded-with-a-status-of-403

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!