Cloud Storage for Firebase позволяет получить список содержимого сегмента Cloud Storage. SDK возвращают как объекты, так и префиксы объектов, на которые ссылается Cloud Storage.
Для проектов, в которых используется List API, требуется Cloud Storage for Firebase Rules версии 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()вернет файл как объект.
SDK Cloud Storage for Firebase не возвращает пути к объектам, которые содержат два последовательных символа / или заканчиваются символом /. Рассмотрим сегмент, в котором есть следующие объекты:
correctPrefix/happyItemwrongPrefix//sadItemlonelyItem/
Операции со списком объектов в этом сегменте дадут следующие результаты:
- Операция list в корневом каталоге возвращает ссылки на
correctPrefix,wrongPrefixиlonelyItemкакprefixes. - Операция list в
correctPrefix/возвращает ссылки наcorrectPrefix/happyItemкакitems. - Операция list в
wrongPrefix/не возвращает ссылки, потому чтоwrongPrefix//sadItemсодержит два последовательных/. - Операция list для
lonelyItem/не возвращает ссылок, потому что объектlonelyItem/заканчивается на/.
Как получить список всех файлов
Вы можете использовать listAll, чтобы получить все результаты для каталога.
Этот вариант лучше всего подходит для небольших каталогов, поскольку все результаты буферизуются в памяти.
Кроме того, если во время выполнения операции объекты добавляются или удаляются, то она может не вернуть согласованный снимок.
Для больших списков используйте метод list() с разбивкой на страницы, так как listAll() буферизует все результаты в памяти.
Ниже приведен пример 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! } });
Разбиение списка результатов на страницы
list() API ограничивает количество возвращаемых результатов. list() обеспечивает единообразный просмотр страниц и предоставляет pageToken, который позволяет контролировать, когда следует получать дополнительные результаты.
Параметр pageToken кодирует путь и версию последнего объекта, возвращенного в предыдущем результате. В последующем запросе с использованием pageToken показываются элементы, которые следуют за pageToken.
В примере ниже показано, как разбить результаты на страницы.
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. } }); }
Обработка ошибок
list() и listAll() не будут работать, если вы не обновите правила безопасности до версии 2. Если вы видите эту ошибку, обновите правила безопасности:
Listing objects in a bucket is disallowed for rules_version = "1".
Please update storage security rules to rules_version = "2" to use list.
Другие ошибки могут указывать на то, что у пользователя нет нужного разрешения. Дополнительную информацию об ошибках можно найти в статье Обработка ошибок.