Cloud Storage for Firebase 可让您快速轻松地将文件上传到 Firebase 提供和管理的 Cloud Storage 存储桶中。
上传文件
如需将文件上传到 Cloud Storage,首先要创建对文件的完整路径(包括文件名)的引用。
Web
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
// 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
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
// '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
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
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
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
// 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!'); });
由于引用定义了文件的完整路径,因此请确保您是将文件上传至非空路径。
添加文件元数据
上传文件时,您还可以指定该文件的元数据。
这些元数据包含典型的文件元数据属性,如 name
、size
和 contentType
(通常称为 MIME 类型)。如果文件存储在磁盘上,Cloud Storage 会利用文件的扩展名自动推断内容类型,但如果您在元数据中指定了 contentType
,指定的内容类型会覆盖自动检测到的类型。如果未指定 contentType
元数据,且文件没有文件扩展名,则 Cloud Storage 默认类型为 application/octet-stream
。如需详细了解文件元数据,请参阅使用文件元数据部分。
Web
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
// 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
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
// 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
观察者 (observer) 中引发进度事件,如:
事件类型 | 典型用法 |
---|---|
running |
此事件在任务开始或恢复上传时触发,通常与 pause 事件结合使用。对于较大的上传作业,此事件可能会随着进度更新多次触发。 |
pause |
每次上传被暂停时,此事件都会触发,通常与 running 事件结合使用。 |
当有事件发生时,系统将传回 TaskSnapshot
对象。此快照是事件发生时任务的视图,该视图不可改变。
此对象包含以下属性:
属性 | 类型 | 说明 |
---|---|---|
bytesTransferred |
Number |
截取快照时已传输的总字节数。 |
totalBytes |
Number |
预期应上传的总字节数。 |
state |
firebase.storage.TaskState |
上传的当前状态。 |
metadata |
firebaseStorage.Metadata |
上传完成前,表示已发送到服务器的元数据。上传完成后,表示服务器发回的元数据。 |
task |
firebaseStorage.UploadTask |
快照所对应的任务,可用于“暂停”“恢复”或“取消”任务。 |
ref |
firebaseStorage.Reference |
此任务的来源引用。 |
将这些状态变化与 TaskSnapshot
的属性相结合,提供了一种简单而强大的方法来监控上传事件。
Web
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
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
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
// 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 下载文件。