Cloud Storage for Firebase 允许您快速轻松地将文件上传到由 Firebase 提供和管理的Cloud Storage 存储桶。
上传文件
要将文件上传到 Cloud Storage,您首先要创建对文件完整路径的引用,包括文件名。
Web version 9
import { getStorage, ref } from "firebase/storage"; // Create a root reference const storage = getStorage(); // Create a reference to 'mountains.jpg' const mountainsRef = ref(storage, 'mountains.jpg'); // Create a reference to 'images/mountains.jpg' const mountainImagesRef = ref(storage, 'images/mountains.jpg'); // While the file names are the same, the references point to different files mountainsRef.name === mountainImagesRef.name; // true mountainsRef.fullPath === mountainImagesRef.fullPath; // false
Web version 8
// Create a root reference var storageRef = firebase.storage().ref(); // Create a reference to 'mountains.jpg' var mountainsRef = storageRef.child('mountains.jpg'); // Create a reference to 'images/mountains.jpg' var mountainImagesRef = storageRef.child('images/mountains.jpg'); // While the file names are the same, the references point to different files mountainsRef.name === mountainImagesRef.name; // true mountainsRef.fullPath === mountainImagesRef.fullPath; // false
从Blob
或File
上传
一旦您创建了适当的引用,您就可以调用uploadBytes()
方法。 uploadBytes()
通过 JavaScript File和Blob API 获取文件并将它们上传到 Cloud Storage。
Web version 9
import { getStorage, ref, uploadBytes } from "firebase/storage"; const storage = getStorage(); const storageRef = ref(storage, 'some-child'); // 'file' comes from the Blob or File API uploadBytes(storageRef, file).then((snapshot) => { console.log('Uploaded a blob or file!'); });
Web version 8
// 'file' comes from the Blob or File API ref.put(file).then((snapshot) => { console.log('Uploaded a blob or file!'); });
从字节数组上传
除了File
和Blob
类型之外, uploadBytes()
还可以将Uint8Array
上传到 Cloud Storage。
Web version 9
import { getStorage, ref, uploadBytes } from "firebase/storage"; const storage = getStorage(); const storageRef = ref(storage, 'some-child'); const bytes = new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21]); uploadBytes(storageRef, bytes).then((snapshot) => { console.log('Uploaded an array!'); });
Web version 8
var bytes = new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21]); ref.put(bytes).then((snapshot) => { console.log('Uploaded an array!'); });
从字符串上传
如果Blob
、 File
或Uint8Array
不可用,您可以使用uploadString()
方法将原始、 base64
、 base64url
或data_url
编码的字符串上传到 Cloud Storage。
Web version 9
import { getStorage, ref, uploadString } from "firebase/storage"; const storage = getStorage(); const storageRef = ref(storage, 'some-child'); // Raw string is the default if no format is provided const message = 'This is my message.'; uploadString(storageRef, message).then((snapshot) => { console.log('Uploaded a raw string!'); }); // Base64 formatted string const message2 = '5b6p5Y+344GX44G+44GX44Gf77yB44GK44KB44Gn44Go44GG77yB'; uploadString(storageRef, message2, 'base64').then((snapshot) => { console.log('Uploaded a base64 string!'); }); // Base64url formatted string const message3 = '5b6p5Y-344GX44G-44GX44Gf77yB44GK44KB44Gn44Go44GG77yB'; uploadString(storageRef, message3, 'base64url').then((snapshot) => { console.log('Uploaded a base64url string!'); }); // Data URL string const message4 = 'data:text/plain;base64,5b6p5Y+344GX44G+44GX44Gf77yB44GK44KB44Gn44Go44GG77yB'; uploadString(storageRef, message4, 'data_url').then((snapshot) => { console.log('Uploaded a data_url string!'); });
Web version 8
// Raw string is the default if no format is provided var message = 'This is my message.'; ref.putString(message).then((snapshot) => { console.log('Uploaded a raw string!'); }); // Base64 formatted string var message = '5b6p5Y+344GX44G+44GX44Gf77yB44GK44KB44Gn44Go44GG77yB'; ref.putString(message, 'base64').then((snapshot) => { console.log('Uploaded a base64 string!'); }); // Base64url formatted string var message = '5b6p5Y-344GX44G-44GX44Gf77yB44GK44KB44Gn44Go44GG77yB'; ref.putString(message, 'base64url').then((snapshot) => { console.log('Uploaded a base64url string!'); }); // Data URL string var message = 'data:text/plain;base64,5b6p5Y+344GX44G+44GX44Gf77yB44GK44KB44Gn44Go44GG77yB'; ref.putString(message, 'data_url').then((snapshot) => { console.log('Uploaded a data_url string!'); });
uploadString()
返回一个UploadTask
,您可以将其用作承诺或用于管理和监控上传状态。
由于引用定义了文件的完整路径,因此请确保您上传到非空路径。
添加文件元数据
上传文件时,您还可以为该文件指定元数据。此元数据包含典型的文件元数据属性,例如name
、 size
和contentType
(通常称为 MIME 类型)。 Cloud Storage 自动根据文件在磁盘上存储的文件扩展名推断内容类型,但如果您在元数据中指定contentType
,它将覆盖自动检测到的类型。如果未指定contentType
元数据并且文件没有文件扩展名,则 Cloud Storage 默认为application/octet-stream
类型。有关文件元数据的更多信息,请参阅使用文件元数据部分。
Web version 9
import { getStorage, ref, uploadBytes } from "firebase/storage"; const storage = getStorage(); const storageRef = ref(storage, 'images/mountains.jpg'); // Create file metadata including the content type /** @type {any} */ const metadata = { contentType: 'image/jpeg', }; // Upload the file and metadata const uploadTask = uploadBytes(storageRef, file, metadata);
Web version 8
// Create file metadata including the content type var metadata = { contentType: 'image/jpeg', }; // Upload the file and metadata var uploadTask = storageRef.child('images/mountains.jpg').put(file, metadata);
管理上传
除了开始上传之外,您还可以使用pause()
、 resume()
和cancel()
方法暂停、恢复和取消上传。调用pause()
或resume()
将引发pause
或running
状态更改。调用cancel()
方法会导致上传失败并返回错误,提示上传已取消。
Web version 9
import { getStorage, ref, uploadBytesResumable } from "firebase/storage"; const storage = getStorage(); const storageRef = ref(storage, 'images/mountains.jpg'); // Upload the file and metadata const uploadTask = uploadBytesResumable(storageRef, file); // Pause the upload uploadTask.pause(); // Resume the upload uploadTask.resume(); // Cancel the upload uploadTask.cancel();
Web version 8
// Upload the file and metadata var uploadTask = storageRef.child('images/mountains.jpg').put(file); // Pause the upload uploadTask.pause(); // Resume the upload uploadTask.resume(); // Cancel the upload uploadTask.cancel();
监控上传进度
上传时,上传任务可能会在state_changed
观察者中引发进度事件,例如:
事件类型 | 典型用法 |
---|---|
running | 该事件在任务开始或恢复上传时触发,通常与pause 事件结合使用。对于较大的上传,此事件可能会作为进度更新触发多次。 |
pause | 此事件会在上传暂停时触发,通常与running 事件结合使用。 |
当事件发生时,会传回一个TaskSnapshot
对象。此快照是事件发生时任务的不可变视图。该对象包含以下属性:
财产 | 类型 | 描述 |
---|---|---|
bytesTransferred | Number | 拍摄此快照时已传输的总字节数。 |
totalBytes | Number | 预计上传的总字节数。 |
state | firebase.storage.TaskState | 上传的当前状态。 |
metadata | firebaseStorage.Metadata | 在上传完成之前,元数据发送到服务器。上传完成后,服务器发回的元数据。 |
task | firebaseStorage.UploadTask | 这是任务的快照,可用于“暂停”、“恢复”或“取消”任务。 |
ref | firebaseStorage.Reference | 此任务的参考来源。 |
这些状态变化与TaskSnapshot
的属性相结合,提供了一种简单而强大的方式来监控上传事件。
Web version 9
import { getStorage, ref, uploadBytesResumable, getDownloadURL } from "firebase/storage"; const storage = getStorage(); const storageRef = ref(storage, 'images/rivers.jpg'); const uploadTask = uploadBytesResumable(storageRef, file); // Register three observers: // 1. 'state_changed' observer, called any time the state changes // 2. Error observer, called on failure // 3. Completion observer, called on successful completion uploadTask.on('state_changed', (snapshot) => { // Observe state change events such as progress, pause, and resume // Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100; console.log('Upload is ' + progress + '% done'); switch (snapshot.state) { case 'paused': console.log('Upload is paused'); break; case 'running': console.log('Upload is running'); break; } }, (error) => { // Handle unsuccessful uploads }, () => { // Handle successful uploads on complete // For instance, get the download URL: https://firebasestorage.googleapis.com/... getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => { console.log('File available at', downloadURL); }); } );
Web version 8
var uploadTask = storageRef.child('images/rivers.jpg').put(file); // Register three observers: // 1. 'state_changed' observer, called any time the state changes // 2. Error observer, called on failure // 3. Completion observer, called on successful completion uploadTask.on('state_changed', (snapshot) => { // Observe state change events such as progress, pause, and resume // 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; } }, (error) => { // Handle unsuccessful uploads }, () => { // Handle successful uploads on complete // For instance, get the download URL: https://firebasestorage.googleapis.com/... uploadTask.snapshot.ref.getDownloadURL().then((downloadURL) => { console.log('File available at', downloadURL); }); } );
错误处理
上传错误的原因有很多,包括本地文件不存在,或者用户没有上传所需文件的权限。有关错误的更多信息,请参阅文档的处理错误部分。
完整示例
带有进度监控和错误处理的上传的完整示例如下所示:
Web version 9
import { getStorage, ref, uploadBytesResumable, getDownloadURL } from "firebase/storage"; const storage = getStorage(); // Create the file metadata /** @type {any} */ const metadata = { contentType: 'image/jpeg' }; // Upload file and metadata to the object 'images/mountains.jpg' const storageRef = ref(storage, 'images/' + file.name); const uploadTask = uploadBytesResumable(storageRef, file, metadata); // Listen for state changes, errors, and completion of the upload. uploadTask.on('state_changed', (snapshot) => { // Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100; console.log('Upload is ' + progress + '% done'); switch (snapshot.state) { case 'paused': console.log('Upload is paused'); break; case 'running': console.log('Upload is running'); break; } }, (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; } }, () => { // Upload completed successfully, now we can get the download URL getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => { console.log('File available at', downloadURL); }); } );
Web version 8
// Create the file metadata var metadata = { contentType: 'image/jpeg' }; // Upload file and metadata to the object 'images/mountains.jpg' var uploadTask = storageRef.child('images/' + file.name).put(file, metadata); // Listen for state changes, errors, and completion of the upload. uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED, // or 'state_changed' (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; } }, (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; } }, () => { // Upload completed successfully, now we can get the download URL uploadTask.snapshot.ref.getDownloadURL().then((downloadURL) => { console.log('File available at', downloadURL); }); } );
现在您已经上传了文件,让我们学习如何从 Cloud Storage下载它们。