Listar archivos con Cloud Storage en Android

Cloud Storage para Firebase le permite enumerar el contenido de su depósito de Cloud Storage. Los SDK devuelven tanto los elementos como los prefijos de los objetos bajo la referencia actual de Cloud Storage.

Los proyectos que usan List API requieren Cloud Storage para Firebase Rules versión 2. Si tienes un proyecto de Firebase existente, sigue los pasos en la Guía de reglas de seguridad .

list() utiliza la API de lista de Google Cloud Storage . En Cloud Storage para Firebase, usamos / como delimitador, lo que nos permite emular la semántica del sistema de archivos. Para permitir un recorrido eficiente de depósitos grandes y jerárquicos de Cloud Storage, la API List devuelve prefijos y elementos por separado. Por ejemplo, si carga un archivo /images/uid/file1 ,

  • root.child('images').listAll() devolverá /images/uid como prefijo.
  • root.child('images/uid').listAll() devolverá el archivo como un elemento.

El SDK de Cloud Storage para Firebase no devuelve rutas de objetos que contengan dos / so consecutivos o terminen con un / . Por ejemplo, considere un depósito que tiene los siguientes objetos:

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

Las operaciones de lista en elementos de este depósito darán los siguientes resultados:

  • La operación de lista en la raíz devuelve las referencias a correctPrefix , wrongPrefix y lonelyItem como prefixes .
  • La operación de lista en correctPrefix/ devuelve las referencias a correctPrefix/happyItem como items .
  • La operación de lista en wrongPrefix/ no devuelve ninguna referencia porque wrongPrefix//sadItem contiene dos / s consecutivos.
  • La operación de lista en lonelyItem/ no devuelve ninguna referencia porque el objeto lonelyItem/ termina con / .

Listar todos los archivos

Puede utilizar listAll para recuperar todos los resultados de un directorio. Esto se utiliza mejor para directorios pequeños ya que todos los resultados se almacenan en la memoria intermedia. Es posible que la operación tampoco devuelva una instantánea coherente si se agregan o eliminan objetos durante el proceso.

Para una lista grande, use el método list() paginado ya que listAll() almacena todos los resultados en la memoria.

El siguiente ejemplo demuestra 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!
            }
        });

Paginar resultados de la lista

La API list() impone un límite a la cantidad de resultados que devuelve. list() proporciona una vista de página consistente y expone un pageToken que permite controlar cuándo obtener resultados adicionales.

El pageToken codifica la ruta y la versión del último elemento devuelto en el resultado anterior. En una solicitud posterior que utiliza el pageToken, se muestran los elementos que vienen después del pageToken.

El siguiente ejemplo demuestra la paginación de un resultado:

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

Manejar errores

list() y listAll() fallan si no ha actualizado las Reglas de seguridad a la versión 2. Actualice sus Reglas de seguridad si ve este error:

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

Otros posibles errores pueden indicar que el usuario no tiene el permiso adecuado. Puede encontrar más información sobre errores en Manejar errores .