在 Android 上使用 Cloud Storage 列出文件

Cloud Storage for Firebase 可讓您列出 Cloud Storage 儲存桶的內容。 SDK 傳回目前 Cloud Storage 引用下的項目和物件的前綴。

使用 List API 的項目需要 Cloud Storage for Firebase 規則版本 2。如果您有現有 Firebase 項目,請依照安全規則指南中的步驟操作。

list()使用Google Cloud Storage List API 。在 Cloud Storage for Firebase 中,我們使用/作為分隔符,這使我們能夠模擬檔案系統語義。為了有效率地遍歷大型分層 Cloud Storage 儲存桶,List API 分別傳回前綴和項目。例如,如果您上傳一個檔案/images/uid/file1

  • root.child('images').listAll()將回傳/images/uid作為前綴。
  • root.child('images/uid').listAll()會將檔案傳回為項目。

Cloud Storage for Firebase SDK 不會傳回包含兩個連續/或以/結尾的物件路徑。例如,考慮一個具有以下物件的儲存桶:

  • correctPrefix/happyItem
  • wrongPrefix//sadItem
  • lonelyItem/

對此儲存桶中的項目進行清單操作將給出以下結果:

  • 根處的列表運算傳回對correctPrefixwrongPrefixlonelyItem的參考作為prefixes
  • correctPrefix/處的清單動作將以items的形式傳回對correctPrefix/happyItem的參考。
  • wrongPrefix/處的清單操作不會傳回任何引用,因為wrongPrefix//sadItem包含兩個連續的/
  • lonelyItem/處的清單運算不會傳回任何引用,因為物件lonelyItem//結尾。

列出所有文件

您可以使用listAll來取得目錄的所有結果。這最適合小目錄,因為所有結果都緩衝在記憶體中。如果在此過程中新增或刪除對象,則該操作也可能不會傳回一致的快照。

對於大型列表,請使用分頁list()方法,因為listAll()將所有結果緩衝在記憶體中。

以下範例示範了listAll

Kotlin+KTX

val storage = Firebase.storage
val listRef = storage.reference.child("files/uid")

// You'll need to import com.google.firebase.storage.component1 and
// com.google.firebase.storage.component2
listRef.listAll()
    .addOnSuccessListener { (items, prefixes) ->
        for (prefix in prefixes) {
            // All the prefixes under listRef.
            // You may call listAll() recursively on them.
        }

        for (item in items) {
            // All the items under listRef.
        }
    }
    .addOnFailureListener {
        // Uh-oh, an error occurred!
    }

Java

StorageReference listRef = storage.getReference().child("files/uid");

listRef.listAll()
        .addOnSuccessListener(new OnSuccessListener<ListResult>() {
            @Override
            public void onSuccess(ListResult listResult) {
                for (StorageReference prefix : listResult.getPrefixes()) {
                    // All the prefixes under listRef.
                    // You may call listAll() recursively on them.
                }

                for (StorageReference item : listResult.getItems()) {
                    // All the items under listRef.
                }
            }
        })
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                // Uh-oh, an error occurred!
            }
        });

將清單結果分頁

list() API 對傳回的結果數量進行了限制。 list()提供一致的頁面瀏覽量並公開 pageToken,允許控制何時取得其他結果。

pageToken 對上一個結果中傳回的最後一項的路徑和版本進行編碼。在使用 pageToken 的後續請求中,將顯示 pageToken 之後的項目。

以下範例示範了對結果進行分頁:

Kotlin+KTX

fun listAllPaginated(pageToken: String?) {
    val storage = Firebase.storage
    val listRef = storage.reference.child("files/uid")

    // Fetch the next page of results, using the pageToken if we have one.
    val listPageTask = if (pageToken != null) {
        listRef.list(100, pageToken)
    } else {
        listRef.list(100)
    }

    // You'll need to import com.google.firebase.storage.component1 and
    // com.google.firebase.storage.component2
    listPageTask
        .addOnSuccessListener { (items, prefixes, pageToken) ->
            // Process page of results
            processResults(items, prefixes)

            // Recurse onto next page
            pageToken?.let {
                listAllPaginated(it)
            }
        }.addOnFailureListener {
            // Uh-oh, an error occurred.
        }
}

Java

public void listAllPaginated(@Nullable String pageToken) {
    FirebaseStorage storage = FirebaseStorage.getInstance();
    StorageReference listRef = storage.getReference().child("files/uid");

    // Fetch the next page of results, using the pageToken if we have one.
    Task<ListResult> listPageTask = pageToken != null
            ? listRef.list(100, pageToken)
            : listRef.list(100);

    listPageTask
            .addOnSuccessListener(new OnSuccessListener<ListResult>() {
                @Override
                public void onSuccess(ListResult listResult) {
                    List<StorageReference> prefixes = listResult.getPrefixes();
                    List<StorageReference> items = listResult.getItems();

                    // Process page of results
                    // ...

                    // Recurse onto next page
                    if (listResult.getPageToken() != null) {
                        listAllPaginated(listResult.getPageToken());
                    }
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    // Uh-oh, an error occurred.
                }
            });
}

處理錯誤

如果您尚未將安全規則升級至版本 2, list()listAll()將會失敗。如果您看到下列錯誤,請升級您的安全性規則:

Listing objects in a bucket is disallowed for rules_version = "1".
Please update storage security rules to rules_version = "2" to use list.

其他可能的錯誤可能表示使用者沒有正確的權限。有關錯誤的更多資訊可以在處理錯誤中找到。