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 最佳做法。使用 FirebaseUI 搭配 Glide 整合功能,即可快速輕鬆地從 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);
處理活動生命週期變更
即使活動生命週期有所變更 (例如顯示對話方塊或旋轉畫面),下載作業仍會在背景繼續進行。您附加的所有事件監聽器也會保持連接。如果在活動停止後呼叫,可能會產生非預期的結果。
如要解決這個問題,您可以使用活動範圍訂閱事件監聽器,以便在活動停止時自動取消註冊。接著,在活動重新啟動時使用 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 的檔案取得及更新中繼資料。