Cloud Storage for Firebase 可让您快速轻松地从 Firebase 提供和管理的 Cloud Storage 存储桶中下载文件。
创建引用
如需下载某个文件,请先为要下载的文件创建一个 Cloud Storage 引用。
您可以通过将子路径附加到 Cloud Storage 存储桶的根目录来创建引用,也可以根据指向 Cloud Storage 中的对象的现有 gs://
或 https://
网址创建引用。
Kotlin+KTX
// Create a storage reference from our app val storageRef = storage.reference // Create a reference with an initial file path and name val pathReference = storageRef.child("images/stars.jpg") // Create a reference to a file from a Google Cloud Storage URI val gsReference = storage.getReferenceFromUrl("gs://bucket/images/stars.jpg") // Create a reference from an HTTPS URL // Note that in the URL, characters are URL escaped! val httpsReference = storage.getReferenceFromUrl( "https://firebasestorage.googleapis.com/b/bucket/o/images%20stars.jpg", )
Java
// Create a storage reference from our app StorageReference storageRef = storage.getReference(); // Create a reference with an initial file path and name StorageReference pathReference = storageRef.child("images/stars.jpg"); // Create a reference to a file from a Google Cloud Storage URI StorageReference gsReference = storage.getReferenceFromUrl("gs://bucket/images/stars.jpg"); // Create a reference from an HTTPS URL // Note that in the URL, characters are URL escaped! StorageReference httpsReference = storage.getReferenceFromUrl("https://firebasestorage.googleapis.com/b/bucket/o/images%20stars.jpg");
下载文件
有了引用之后,您便可以调用 getBytes()
或 getStream()
方法从 Cloud Storage 下载文件。如果您希望使用其他的库下载文件,则可以使用 getDownloadUrl()
方法获取下载网址。
下载至内存
您可以使用 getBytes()
方法将文件下载到 byte[]
。这是最简单的文件下载方法,但它必须将文件的全部内容加载到内存中。如果您请求下载的文件大于应用的可用内存,应用将会崩溃。为防止出现内存问题,可以为 getBytes()
设置一个下载字节数上限参数。请将该上限设为您知道应用可以处理的大小,或者使用其他下载方法。
Kotlin+KTX
var islandRef = storageRef.child("images/island.jpg") val ONE_MEGABYTE: Long = 1024 * 1024 islandRef.getBytes(ONE_MEGABYTE).addOnSuccessListener { // Data for "images/island.jpg" is returned, use this as needed }.addOnFailureListener { // Handle any errors }
Java
StorageReference islandRef = storageRef.child("images/island.jpg"); final long ONE_MEGABYTE = 1024 * 1024; islandRef.getBytes(ONE_MEGABYTE).addOnSuccessListener(new OnSuccessListener<byte[]>() { @Override public void onSuccess(byte[] bytes) { // Data for "images/island.jpg" is returns, use this as needed } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception exception) { // Handle any errors } });
下载至本地文件
getFile()
方法可将文件直接下载至本地设备。如果用户希望离线时可以访问文件或希望在不同的应用中共享文件,请使用这种方法。getFile()
会返回一个 DownloadTask
,您可以使用它来管理下载并监控下载状态。
Kotlin+KTX
islandRef = storageRef.child("images/island.jpg") val localFile = File.createTempFile("images", "jpg") islandRef.getFile(localFile).addOnSuccessListener { // Local temp file has been created }.addOnFailureListener { // Handle any errors }
Java
islandRef = storageRef.child("images/island.jpg"); File localFile = File.createTempFile("images", "jpg"); islandRef.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() { @Override public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) { // Local temp file has been created } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception exception) { // Handle any errors } });
如果您希望手动管理下载,请参阅管理下载以了解详情。
通过网址下载数据
如果您已经有了基于网址的下载基础架构,或者只需要一个网址用于共享,可通过对 Cloud Storage 引用调用 getDownloadUrl()
方法来获取文件的下载网址。
Kotlin+KTX
storageRef.child("users/me/profile.png").downloadUrl.addOnSuccessListener { // Got the download URL for 'users/me/profile.png' }.addOnFailureListener { // Handle any errors }
Java
storageRef.child("users/me/profile.png").getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() { @Override public void onSuccess(Uri uri) { // Got the download URL for 'users/me/profile.png' } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception exception) { // Handle any errors } });
通过 FirebaseUI 下载图片
FirebaseUI 提供简单、可定制且适合生产环境的原生移动绑定,以消除样板代码并促进遵循 Google 最佳实践。借助与 Glide 的集成,您可以使用 FirebaseUI 快速轻松地下载、缓存和显示 Cloud Storage 中的图片。
首先,将 FirebaseUI 添加到您的 app/build.gradle
文件:
dependencies { // FirebaseUI Storage only implementation 'com.firebaseui:firebase-ui-storage:7.2.0' }
然后,您可以直接将 Cloud Storage 中的图片加载到 ImageView
:
Kotlin+KTX
// Reference to an image file in Cloud Storage val storageReference = Firebase.storage.reference // ImageView in your Activity val imageView = findViewById<ImageView>(R.id.imageView) // Download directly from StorageReference using Glide // (See MyAppGlideModule for Loader registration) Glide.with(context) .load(storageReference) .into(imageView)
Java
// Reference to an image file in Cloud Storage StorageReference storageReference = FirebaseStorage.getInstance().getReference(); // ImageView in your Activity ImageView imageView = findViewById(R.id.imageView); // Download directly from StorageReference using Glide // (See MyAppGlideModule for Loader registration) Glide.with(context) .load(storageReference) .into(imageView);
处理 Activity 生命周期变更
即使 activity 生命周期发生变化(例如显示对话框或旋转屏幕),下载也将继续在后台进行。您连接的所有监听器也都会保持连接状态。如果在 activity 停止后调用这些监听器,有可能产生意外的结果。
您可以采取以下方法来解决此问题:向 activity 作用域订阅您的监听器,以便在 activity 停止时自动取消注册。然后,在 activity 重启后使用 getActiveDownloadTasks
方法获取仍在进行或刚刚完成的下载任务。
下面的示例演示了这一操作,还说明了如何保留使用的存储引用路径。
Kotlin+KTX
override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) // If there's a download in progress, save the reference so you can query it later outState.putString("reference", storageRef.toString()) } override fun onRestoreInstanceState(savedInstanceState: Bundle) { super.onRestoreInstanceState(savedInstanceState) // If there was a download in progress, get its reference and create a new StorageReference val stringRef = savedInstanceState.getString("reference") ?: return storageRef = Firebase.storage.getReferenceFromUrl(stringRef) // Find all DownloadTasks under this StorageReference (in this example, there should be one) val tasks = storageRef.activeDownloadTasks if (tasks.size > 0) { // Get the task monitoring the download val task = tasks[0] // Add new listeners to the task using an Activity scope task.addOnSuccessListener(this) { // Success! // ... } } }
Java
@Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // If there's a download in progress, save the reference so you can query it later if (mStorageRef != null) { outState.putString("reference", mStorageRef.toString()); } } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); // If there was a download in progress, get its reference and create a new StorageReference final String stringRef = savedInstanceState.getString("reference"); if (stringRef == null) { return; } mStorageRef = FirebaseStorage.getInstance().getReferenceFromUrl(stringRef); // Find all DownloadTasks under this StorageReference (in this example, there should be one) List<FileDownloadTask> tasks = mStorageRef.getActiveDownloadTasks(); if (tasks.size() > 0) { // Get the task monitoring the download FileDownloadTask task = tasks.get(0); // Add new listeners to the task using an Activity scope task.addOnSuccessListener(this, new OnSuccessListener<FileDownloadTask.TaskSnapshot>() { @Override public void onSuccess(FileDownloadTask.TaskSnapshot state) { // Success! // ... } }); } }
处理错误
导致下载出错的原因有很多,包括文件不存在,或者用户不具备访问相应文件的权限。如需了解有关错误的详细信息,请参阅文档的处理错误部分。
完整示例
包含错误处理的下载完整示例如下:
Kotlin+KTX
storageRef.child("users/me/profile.png").getBytes(Long.MAX_VALUE).addOnSuccessListener { // Use the bytes to display the image }.addOnFailureListener { // Handle any errors }
Java
storageRef.child("users/me/profile.png").getBytes(Long.MAX_VALUE).addOnSuccessListener(new OnSuccessListener<byte[]>() { @Override public void onSuccess(byte[] bytes) { // Use the bytes to display the image } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception exception) { // Handle any errors } });
对于存储在 Cloud Storage 中的文件,您还可以获取和更新元数据。