Lister des fichiers avec Cloud Storage sur les plates-formes Apple

Cloud Storage for Firebase vous permet de lister le contenu de votre bucket Cloud Storage. Les SDK renvoient à la fois les éléments et les préfixes des objets sous la référence Cloud Storage actuelle.

Les projets qui utilisent l'API de liste nécessitent la version 2 des règles Cloud Storage for Firebase. Si vous avez un projet Firebase existant, suivez les étapes décrites dans le guide des règles de sécurité.

list() utilise l'API List Google Cloud Storage. Dans Cloud Storage for Firebase, nous utilisons / comme séparateur, ce qui nous permet d'émuler la sémantique du système de fichiers. Pour permettre une traversée efficace de grands buckets Cloud Storage hiérarchiques, l'API List renvoie les préfixes et les éléments séparément. Par exemple, si vous importez un fichier /images/uid/file1,

  • root.child('images').listAll() renvoie /images/uid en tant que préfixe.
  • root.child('images/uid').listAll() renvoie le fichier en tant qu'élément.

Le SDK Cloud Storage for Firebase ne renvoie pas de chemins d'objets contenant deux / consécutifs ou se terminant par un /.. Prenons l'exemple d'un bucket contenant les objets suivants:

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

Les opérations de liste sur les éléments de ce bucket donneront les résultats suivants:

  • L'opération de liste à la racine renvoie les références à correctPrefix, wrongPrefix et lonelyItem sous la forme prefixes.
  • L'opération de liste au niveau de correctPrefix/ renvoie les références à correctPrefix/happyItem sous la forme items.
  • L'opération de liste au niveau de wrongPrefix/ ne renvoie aucune référence, car wrongPrefix//sadItem contient deux / consécutifs.
  • L'opération de liste au niveau de lonelyItem/ ne renvoie aucune référence, car l'objet lonelyItem/ se termine par /.

Répertorier tous les fichiers

Vous pouvez utiliser listAll(completion:) pour récupérer tous les résultats d'un répertoire. Cette option est particulièrement adaptée aux petits répertoires, car tous les résultats sont mis en mémoire tampon. L'opération peut également ne pas renvoyer d'instantané cohérent si des objets sont ajoutés ou supprimés au cours du processus.

Pour une liste volumineuse, utilisez la méthode list(withMaxResults:completion:) paginée, car listAll(completion:) met en mémoire tampon tous les résultats.

L'exemple suivant illustre listAll(completion:).

Swift

let storageReference = storage.reference().child("files/uid")
do {
  let result = try await storageReference.listAll()
  for prefix in result.prefixes {
    // The prefixes under storageReference.
    // You may call listAll(completion:) recursively on them.
  }
  for item in result.items {
    // The items under storageReference.
  }
} catch {
  // ...
}

Objective-C

FIRStorageReference *storageReference = [storage reference];
[storageReference listAllWithCompletion:^(FIRStorageListResult *result, NSError *error) {
  if (error != nil) {
    // ...
  }

  for (FIRStorageReference *prefix in result.prefixes) {
    // All the prefixes under storageReference.
    // You may call listAllWithCompletion: recursively on them.
  }
  for (FIRStorageReference *item in result.items) {
    // All items under storageReference.
  }
}];

Paginer les résultats d'une liste

L'API list(withMaxResults:completion:) limite le nombre de résultats qu'elle renvoie. list(withMaxResults:completion) fournit une page vue cohérente et expose un pageToken qui permet de contrôler le moment où extraire des résultats supplémentaires.

Le pageToken encode le chemin d'accès et la version du dernier élément renvoyé dans le résultat précédent. Dans une requête ultérieure utilisant le pageToken, les éléments qui suivent le pageToken sont affichés.

L'exemple suivant illustre la pagination d'un résultat:

Swift

func listAllPaginated(pageToken: String? = nil) async throws {
  let storage = Storage.storage()
  let storageReference = storage.reference().child("files/uid")

  let listResult: StorageListResult
  if let pageToken = pageToken {
    listResult = try await storageReference.list(maxResults: 100, pageToken: pageToken)
  } else {
    listResult = try await storageReference.list(maxResults: 100)
  }
  let prefixes = listResult.prefixes
  let items = listResult.items
  // Handle list result
  // ...

  // Process next page
  if let token = listResult.pageToken {
    try await listAllPaginated(pageToken: token)
  }
}

Objective-C

- (void)paginateFilesAtReference:(FIRStorageReference *)reference
                       pageToken:(nullable NSString *)pageToken {
  void (^pageHandler)(FIRStorageListResult *_Nonnull, NSError *_Nullable) =
      ^(FIRStorageListResult *result, NSError *error) {
        if (error != nil) {
          // ...
        }
        NSArray *prefixes = result.prefixes;
        NSArray *items = result.items;

        // ...

        // Process next page
        if (result.pageToken != nil) {
          [self paginateFilesAtReference:reference pageToken:result.pageToken];
        }
  };

  if (pageToken != nil) {
    [reference listWithMaxResults:100 pageToken:pageToken completion:pageHandler];
  } else {
    [reference listWithMaxResults:100 completion:pageHandler];
  }
}

Gérer les erreurs

Les méthodes de l'API de liste échoueront si vous n'avez pas mis à niveau vos règles de sécurité vers la version 2. Mettez à niveau vos règles de sécurité si cette erreur s'affiche:

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

D'autres erreurs peuvent indiquer que l'utilisateur ne dispose pas des autorisations appropriées. Pour en savoir plus sur les erreurs, consultez la section Gérer les erreurs.