问题
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