在 iOS 上列出文件

借助 Cloud Storage,您可以列出存储分区的内容。SDK 会返回当前存储引用下的对象的项和前缀。

使用 List API 的项目需要 Firebase 存储规则版本 2。如果您已有一个 Firebase 项目,请按照安全规则指南中的步骤操作。

List API 使用 Google Cloud Storage 的 List API。在 Firebase 存储中,我们使用 / 作为分隔符来模拟文件系统语义。为了高效遍历大型分层存储分区,List API 分别返回前缀和项。例如,如果您上传一个文件 /images/uid/file1,则:

  • root.child('images').listAll() 将返回 /images/uid 作为前缀。
  • root.child('images/uid').listAll() 将返回该文件作为项。

Firebase 存储 SDK 不会返回包含两个连续的 / 或以 /..结尾的对象路径。例如,如果存储分区包含以下对象:

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

则对此存储分区中的项执行列出操作生成的结果如下:

  • 在根目录中执行列出操作将返回对作为 prefixescorrectPrefixwrongPrefixlonelyItem 的引用。
  • correctPrefix/ 中执行列出操作将返回对作为 itemscorrectPrefix/happyItem 的引用。
  • wrongPrefix/ 中执行列出操作不会返回任何引用,因为 wrongPrefix//sadItem 包含两个连续的 /
  • lonelyItem/ 中执行列出操作不会返回任何引用,因为对象 以 / 结尾。

列出所有文件

您可以使用 listAll(completion:) 提取目录的所有结果。此方法最适合用于小型目录,因为所有结果都会保留在内存缓冲区中。如果在此过程中添加或移除了对象,则该操作也可能不会返回一致的快照。

对于大型列表,则适合使用分页的 list(withMaxResults:completion:) 方法,因为 listAll(completion:) 会在内存缓冲区中保留所有结果。

以下示例演示了 listAll(completion:)

Swift

let storageReference = storage.reference().child("files/uid")
storageReference.listAll { (result, error) in
  if let error = error {
    // ...
  }
  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.
  }
}

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

将列出结果分页

list(withMaxResults:completion:) API 对返回的结果数设置了限制。list(withMaxResults:completion) 提供了一致的网页浏览,并公开了一个可让您控制何时提取其他结果的 pageToken。

该 pageToken 会对上一条结果中返回的最后一项的路径和版本进行编码。在使用该 pageToken 的后续请求中,位于 pageToken 后面的项会显示。

以下示例演示了如何将结果分页:

Swift

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

  let pageHandler: (StorageListResult, Error?) -> Void = { (result, error) in
    if let error = error {
      // ...
    }
    let prefixes = result.prefixes
    let items = result.items

    // ...

    // Process next page
    if let token = result.pageToken {
      self.listAllPaginated(pageToken: token)
    }
  }

  if let pageToken = pageToken {
    storageReference.list(withMaxResults: 100, pageToken: pageToken, completion: pageHandler)
  } else {
    storageReference.list(withMaxResults: 100, completion: pageHandler)
  }
}

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];
  }
}

处理错误

如果您尚未将安全规则升级到版本 2,则 List API 中的方法将失败。如果您看到以下错误消息,请升级您的安全规则:

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

系统也可能会显示其他错误消息,指出用户没有适当的权限。如需详细了解这些错误,请参阅处理错误