Liệt kê tệp bằng Cloud Storage trên Android

Cloud Storage for Firebase cho phép bạn liệt kê nội dung của nhóm lưu trữ Cloud Storage. SDK trả về cả các mục và tiền tố của đối tượng trong tham chiếu Cloud Storage hiện tại.

Các dự án sử dụng List API yêu cầu Cloud Storage for Firebase Rules phiên bản 2. Nếu bạn có một dự án Firebase hiện tại, hãy làm theo các bước trong Hướng dẫn về quy tắc bảo mật.

list() sử dụng Google Cloud Storage List API. Trong Cloud Storage for Firebase, chúng tôi sử dụng / làm dấu phân cách, cho phép chúng tôi mô phỏng ngữ nghĩa của hệ thống tệp. Để cho phép duyệt hiệu quả các nhóm lưu trữ lớn, có cấu trúc phân cấp Cloud Storage, List API sẽ trả về tiền tố và mục riêng biệt. Ví dụ: nếu bạn tải một tệp /images/uid/file1 lên,

  • root.child('images').listAll() sẽ trả về /images/uid dưới dạng tiền tố.
  • root.child('images/uid').listAll() sẽ trả về tệp dưới dạng một mục.

SDK không trả về đường dẫn đối tượng chứa hai dấu / liên tiếp hoặc kết thúc bằng dấu /.Cloud Storage for Firebase Ví dụ: hãy xem xét một nhóm lưu trữ có các đối tượng sau:

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

Các thao tác liệt kê trên các mục trong nhóm lưu trữ này sẽ cho kết quả như sau:

  • Thao tác liệt kê ở gốc trả về các tham chiếu đến correctPrefix, wrongPrefixlonelyItem dưới dạng prefixes.
  • Thao tác liệt kê tại correctPrefix/ trả về các tham chiếu đến correctPrefix/happyItem dưới dạng items.
  • Thao tác liệt kê tại wrongPrefix/ không trả về tham chiếu nào vì wrongPrefix//sadItem chứa hai dấu / liên tiếp.
  • Thao tác liệt kê tại lonelyItem/ không trả về tham chiếu nào vì đối tượng lonelyItem/ kết thúc bằng /.

Liệt kê tất cả các tệp

Bạn có thể sử dụng listAll để tìm nạp tất cả kết quả cho một thư mục. Cách này phù hợp nhất cho các thư mục nhỏ vì tất cả kết quả đều được lưu vào bộ nhớ. Thao tác này cũng có thể không trả về ảnh chụp nhanh nhất quán nếu các đối tượng được thêm hoặc xoá trong quá trình này.

Đối với danh sách lớn, hãy sử dụng phương thức list() được phân trang vì listAll() lưu tất cả kết quả vào bộ nhớ.

Ví dụ sau đây minh hoạ listAll.

Kotlin

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!
            }
        });

Phân trang kết quả danh sách

API list() đặt giới hạn về số lượng kết quả mà API này trả về. list() cung cấp một lượt xem trang nhất quán và hiển thị một pageToken cho phép kiểm soát thời điểm tìm nạp thêm kết quả.

pageToken mã hoá đường dẫn và phiên bản của mục cuối cùng được trả về trong kết quả trước đó. Trong một yêu cầu tiếp theo sử dụng pageToken, các mục xuất hiện sau pageToken sẽ được hiển thị.

Ví dụ sau đây minh hoạ cách phân trang kết quả:

Kotlin

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.
                }
            });
}

Xử lý lỗi

list()listAll() sẽ không thành công nếu bạn chưa nâng cấp Quy tắc bảo mật lên phiên bản 2. Hãy nâng cấp Quy tắc bảo mật nếu bạn thấy lỗi này:

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

Các lỗi có thể xảy ra khác có thể cho biết người dùng không có quyền phù hợp. Bạn có thể xem thêm thông tin về lỗi trong phần Xử lý lỗi.