Cloud Storage for Firebase 可让您快速轻松地将文件上传到 Firebase 提供和管理的 Cloud Storage 存储桶中。
上传文件
如需将文件上传到 Cloud Storage,首先要创建对文件的完整路径(包括文件名)的引用。
// Create a storage reference from our app
final storageRef = FirebaseStorage.instance.ref();
// Create a reference to "mountains.jpg"
final mountainsRef = storageRef.child("mountains.jpg");
// Create a reference to 'images/mountains.jpg'
final mountainImagesRef = storageRef.child("images/mountains.jpg");
// While the file names are the same, the references point to different files
assert(mountainsRef.name == mountainImagesRef.name);
assert(mountainsRef.fullPath != mountainImagesRef.fullPath);
创建适当的引用后,您可以调用 putFile()
、putString()
或 putData()
方法将文件上传到 Cloud Storage。
您无法通过指向 Cloud Storage 存储桶根目录的引用来上传数据。您的引用必须指向一个子网址。
通过文件上传
如需上传文件,您必须先获取其设备端位置的绝对路径。例如,如果某个文件存在于应用的文档目录中,请使用官方的 path_provider
软件包生成文件路径并将其传递给 putFile()
:
Directory appDocDir = await getApplicationDocumentsDirectory();
String filePath = '${appDocDir.absolute}/file-to-upload.png';
File file = File(filePath);
try {
await mountainsRef.putFile(file);
} on firebase_core.FirebaseException catch (e) {
// ...
}
通过字符串上传
您可以使用 putString()
方法以原始字符串或 base64
、base64url
、data_url
编码字符串形式上传数据。例如,如需上传编码为数据网址的文本字符串,请使用以下代码:
String dataUrl = 'data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==';
try {
await mountainsRef.putString(dataUrl, format: PutStringFormat.dataUrl);
} on FirebaseException catch (e) {
// ...
}
上传原始数据
对于不便上传字符串或文件的情况,您可以采用 Uint8List
的形式上传较低级类型的数据。在这种情况下,请使用您的数据调用 putData()
方法:
try {
// Upload raw data.
await mountainsRef.putData(data);
} on firebase_core.FirebaseException catch (e) {
// ...
}
获取下载网址
上传文件后,您可以调用 Reference
的 getDownloadUrl()
方法,获取下载文件的网址:
await mountainsRef.getDownloadURL();
添加文件元数据
在上传文件时,您还可以包含元数据。这些元数据包含典型的文件元数据属性,如 contentType
(通常称为 MIME 类型)。putFile()
方法会自动根据 File
扩展名推断 MIME 类型,您也可以在元数据中指定 contentType
,覆盖自动检测到的类型。如果您未提供 contentType
,并且 Cloud Storage 无法根据文件扩展名推断出默认值,Cloud Storage 将使用 application/octet-stream
。请参阅使用文件元数据。
try {
await mountainsRef.putFile(file, SettableMetadata(
contentType: "image/jpeg",
));
} on firebase_core.FirebaseException catch (e) {
// ...
}
管理上传
除了启动上传外,您还可以分别使用 pause()
、resume()
和 cancel()
方法来暂停、恢复和取消上传。暂停和恢复事件会分别导致状态变为 pause
和 progress
。取消上传会导致上传失败,并显示一条错误指明上传已被取消。
final task = mountainsRef.putFile(largeFile);
// Pause the upload.
bool paused = await task.pause();
print('paused, $paused');
// Resume the upload.
bool resumed = await task.resume();
print('resumed, $resumed');
// Cancel the upload.
bool canceled = await task.cancel();
print('canceled, $canceled');
监控上传进度
您可以监听任务的事件流来处理上传任务中的成功、失败、进度或暂停等各种情况:
事件类型 | 典型用法 |
---|---|
TaskState.running |
在数据传输期间定期触发,可用于为上传/下载进度指示器提供显示数据。 |
TaskState.paused |
在任务每次暂停时触发。 |
TaskState.success |
在任务成功完成时触发。 |
TaskState.canceled |
在任务每次取消时触发。 |
TaskState.error |
在上传失败时触发。网络超时、授权失败或取消任务时会发生此事件。 |
mountainsRef.putFile(file).snapshotEvents.listen((taskSnapshot) {
switch (taskSnapshot.state) {
case TaskState.running:
// ...
break;
case TaskState.paused:
// ...
break;
case TaskState.success:
// ...
break;
case TaskState.canceled:
// ...
break;
case TaskState.error:
// ...
break;
}
});
错误处理
导致上传时出错的原因有很多,包括本地文件不存在,或者用户不具备上传相应文件的权限。如需了解错误详情,请参阅相关文档的处理错误部分。
完整示例
下面是一个包含进度监控和错误处理的完整上传示例:
final appDocDir = await getApplicationDocumentsDirectory();
final filePath = "${appDocDir.absolute}/path/to/mountains.jpg";
final file = File(filePath);
// Create the file metadata
final metadata = SettableMetadata(contentType: "image/jpeg");
// Create a reference to the Firebase Storage bucket
final storageRef = FirebaseStorage.instance.ref();
// Upload file and metadata to the path 'images/mountains.jpg'
final uploadTask = storageRef
.child("images/path/to/mountains.jpg")
.putFile(file, metadata);
// Listen for state changes, errors, and completion of the upload.
uploadTask.snapshotEvents.listen((TaskSnapshot taskSnapshot) {
switch (taskSnapshot.state) {
case TaskState.running:
final progress =
100.0 * (taskSnapshot.bytesTransferred / taskSnapshot.totalBytes);
print("Upload is $progress% complete.");
break;
case TaskState.paused:
print("Upload is paused.");
break;
case TaskState.canceled:
print("Upload was canceled");
break;
case TaskState.error:
// Handle unsuccessful uploads
break;
case TaskState.success:
// Handle successful uploads on complete
// ...
break;
}
});
现在您已经上传了文件,接下来,我们将学习如何从 Cloud Storage 中下载文件。