使用 Cloud Storage 列出文件 (Web)

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

使用 List API 的项目需要 Cloud Storage for Firebase 规则版本 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() 将返回该文件作为项。

Cloud Storage for Firebase SDK 不会返回包含两个连续的 / 或以 /. 结尾的对象路径。例如,假设一个存储桶中包含以下对象:

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

对此存储桶中的项执行列出操作返回的结果如下:

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

列出所有文件

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

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

以下示例演示了 listAll

Web

import { getStorage, ref, listAll } from "firebase/storage";

const storage = getStorage();

// Create a reference under which you want to list
const listRef = ref(storage, 'files/uid');

// Find all the prefixes and items.
listAll(listRef)
  .then((res) => {
    res.prefixes.forEach((folderRef) => {
      // All the prefixes under listRef.
      // You may call listAll() recursively on them.
    });
    res.items.forEach((itemRef) => {
      // All the items under listRef.
    });
  }).catch((error) => {
    // Uh-oh, an error occurred!
  });

Web

// Create a reference under which you want to list
var listRef = storageRef.child('files/uid');

// Find all the prefixes and items.
listRef.listAll()
  .then((res) => {
    res.prefixes.forEach((folderRef) => {
      // All the prefixes under listRef.
      // You may call listAll() recursively on them.
    });
    res.items.forEach((itemRef) => {
      // All the items under listRef.
    });
  }).catch((error) => {
    // Uh-oh, an error occurred!
  });

将列出的结果分页

list() API 对返回的结果数设置了限制。list() 会提供一致的分页视图,并提供一个让您可以控制何时提取更多结果的 pageToken。

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

以下示例演示了如何使用 async/await 对结果进行分页。

Web

import { getStorage, ref, list } from "firebase/storage";

async function pageTokenExample(){
  // Create a reference under which you want to list
  const storage = getStorage();
  const listRef = ref(storage, 'files/uid');

  // Fetch the first page of 100.
  const firstPage = await list(listRef, { maxResults: 100 });

  // Use the result.
  // processItems(firstPage.items)
  // processPrefixes(firstPage.prefixes)

  // Fetch the second page if there are more elements.
  if (firstPage.nextPageToken) {
    const secondPage = await list(listRef, {
      maxResults: 100,
      pageToken: firstPage.nextPageToken,
    });
    // processItems(secondPage.items)
    // processPrefixes(secondPage.prefixes)
  }
}

Web

async function pageTokenExample(){
  // Create a reference under which you want to list
  var listRef = storageRef.child('files/uid');

  // Fetch the first page of 100.
  var firstPage = await listRef.list({ maxResults: 100});

  // Use the result.
  // processItems(firstPage.items)
  // processPrefixes(firstPage.prefixes)

  // Fetch the second page if there are more elements.
  if (firstPage.nextPageToken) {
    var secondPage = await listRef.list({
      maxResults: 100,
      pageToken: firstPage.nextPageToken,
    });
    // processItems(secondPage.items)
    // processPrefixes(secondPage.prefixes)
  }
}

处理错误

如果您尚未将安全规则升级到版本 2,则 list()listAll() 将返回被拒绝的 Promise。如果您看到以下错误,请升级您的安全规则:

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

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