Elencare i file con Cloud Storage su Android

Cloud Storage for Firebase consente di elencare i contenuti del bucket Cloud Storage. Gli SDK restituiscono sia gli elementi sia i prefissi degli oggetti nel riferimento Cloud Storage corrente.

I progetti che utilizzano l'API List richiedono la versione 2 delle regole Cloud Storage for Firebase. Se hai già un progetto Firebase, segui i passaggi descritti nella Guida alle regole di sicurezza.

list() utilizza l'Google Cloud Storage API List. In Cloud Storage for Firebase, utilizziamo / come delimitatore, il che ci consente di emulare la semantica del file system. Per consentire l'attraversamento efficiente di bucket Cloud Storage di grandi dimensioni e gerarchici, l'API List restituisce prefissi e elementi separatamente. Ad esempio, se carichi un file /images/uid/file1,

  • root.child('images').listAll() restituirà /images/uid come prefisso.
  • root.child('images/uid').listAll() restituirà il file come elemento.

L'SDK Cloud Storage for Firebase non restituisce percorsi di oggetti che contengono due / consecutivi o che terminano con un /. Ad esempio, considera un bucket con i seguenti oggetti:

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

Le operazioni di elenco sugli elementi in questo bucket daranno i seguenti risultati:

  • L'operazione di elenco nella radice restituisce i riferimenti a correctPrefix, wrongPrefix e lonelyItem come prefixes.
  • L'operazione di elenco in correctPrefix/ restituisce i riferimenti a correctPrefix/happyItem come items.
  • L'operazione di elenco in wrongPrefix/ non restituisce alcun riferimento perché wrongPrefix//sadItem contiene due / consecutivi.
  • L'operazione di elenco in lonelyItem/ non restituisce alcun riferimento perché l'oggetto lonelyItem/ termina con /.

Elenca tutti i file

Puoi utilizzare listAll per recuperare tutti i risultati di una directory. È ideale per directory di piccole dimensioni, poiché tutti i risultati vengono memorizzati nel buffer in memoria. L'operazione potrebbe anche non restituire uno snapshot coerente se gli oggetti vengono aggiunti o rimossi durante il processo.

Per un elenco di grandi dimensioni, utilizza il metodo list() paginato, in quanto listAll() memorizza nel buffer tutti i risultati.

L'esempio seguente mostra 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!
            }
        });

Impagina i risultati dell'elenco

L'API list() impone un limite al numero di risultati restituiti. list() fornisce una visualizzazione di pagina coerente ed espone un pageToken che consente di controllare quando recuperare risultati aggiuntivi.

pageToken codifica il percorso e la versione dell'ultimo elemento restituito nel risultato precedente. In una richiesta successiva che utilizza pageToken, vengono mostrati gli elementi che seguono pageToken.

L'esempio seguente mostra la paginazione di un risultato:

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

Gestisci gli errori

list() e listAll() non riescono se non hai eseguito l'upgrade delle regole di sicurezza alla versione 2. Aggiorna le regole di sicurezza se visualizzi questo errore:

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

Altri possibili errori potrebbero indicare che l'utente non dispone dell'autorizzazione corretta. Per maggiori informazioni sugli errori, consulta la sezione Gestire gli errori.