【问题标题】:How do I list all the paths and directories in my Firebase Storage with Flutter?如何使用 Flutter 列出 Firebase 存储中的所有路径和目录?
【发布时间】:2021-12-23 21:10:52
【问题描述】:

我正在使用 Flutter,在我的 Firebase 存储中,我有一个复杂的文件和目录架构。我想列出 Firebase 存储中包含的所有文件(包括它们的路径),以便下载它们并将它们存储在设备的本地存储中。

我知道如何列出一个文件夹中的所有文件,但是如何在不知道这些文件夹名称的情况下同时列出所有文件夹中的文件?

例如,我的架构可能如下所示:

MainFolder
  -- Folder2
    -- Folder3
      -- file.json
    -- Folder4
      -- file2.json
AnotherMainFolder
  -- file3.json

我的 Firebase 存储中的结构是动态的(我不知道其中的目录名称和数量)。

到目前为止,我已经设法编写了以下代码:

class DownloadFirebaseApi {
  static Future<List<FirebaseFile>> listAll() async {
    // here, I should specify a path `ref(path)`
    // however I don't want to because
    // I want all the folders and all the files
    // no matter in which directory they are
    final ref = FirebaseStorage.instance.ref();
    final result = await ref.listAll();
    final urls = await _getDownloadLinks(result.items);
    return urls
        .asMap()
        .map((index, url) {
          final ref = result.items[index];
          final name = ref.name;
          final file = FirebaseFile(name: name, url: url, ref: ref);
          return MapEntry(index, file);
        })
        .values
        .toList();
  }

  static Future<List<String>> _getDownloadLinks(List<Reference> refs) async {
    return Future.wait(refs.map((ref) {
      var url = ref.getDownloadURL();
      return ref.getDownloadURL();
    }).toList());
  }
}

对于listAll(),有我不知道的递归方法吗?

【问题讨论】:

    标签: firebase flutter firebase-storage


    【解决方案1】:

    当您调用listAll 时,结果有两个列表:

    1. result.items,其中包含根目录中的所有单个文件。
    2. result.prefixes,包含所有目录(在 Cloud Storage 中通常称为“前缀”)。

    您还需要循环遍历 result.prefixes,并依次调用每个 listAll 以获得完整的递归文件列表。

    另请参阅listing files and directories 上的 FlutterFire 文档。

    【讨论】:

      【解决方案2】:

      对于那些有兴趣了解我如何编写代码的人(感谢 Frank van Puffelen 的回答)

      import 'package:firebase_storage/firebase_storage.dart';
      
      class FirebaseFile {
        final Reference ref;
        final String url;
        final String name;
      
        FirebaseFile({
          required this.ref,
          required this.url,
          required this.name,
        });
      
        @override
        String toString() {
          return 'file "$name"';
        }
      }
      
      class DownloadFirebaseApi {
        /// Transform the items (the files) contained in the [result] (a folder).
        /// The items are transformed into a list of [FirebaseFile] objects.
        static Future<List<FirebaseFile>> _getFilesFrom(ListResult result) async {
          List<String> urls = await _getDownloadLinks(result.items);
          return urls
              .asMap()
              .map((index, url) {
                final ref = result.items[index];
                final name = ref.name;
                final file = FirebaseFile(name: name, url: url, ref: ref);
                return MapEntry(index, file);
              })
              .values
              .toList();
        }
      
        /// Explores all the nested directories and
        /// returns a list of all the files as [FirebaseFile] objects.
        static Future<List<FirebaseFile>> _exploreDirectories(
          ListResult result,
        ) async {
          List<FirebaseFile> files = [];
          if (result.prefixes.isEmpty) {
            if (result.items.isEmpty) {
              return [];
            } else {
              return await _getFilesFrom(result);
            }
          } else {
            for (Reference prefix in result.prefixes) {
              ListResult nestedResult = await prefix.listAll();
              if (nestedResult.items.isNotEmpty) {
                files.addAll(await _getFilesFrom(nestedResult));
              }
              if (nestedResult.prefixes.isNotEmpty) {
                files.addAll(await _exploreDirectories(nestedResult));
              }
            }
          }
          return files;
        }
      
        /// Returns a list of all the files as [FirebaseFile] objects.
        static Future<List<FirebaseFile>> listAll() async {
          final ref = FirebaseStorage.instance.ref();
          List<FirebaseFile> files = [];
          ListResult result = await ref.listAll();
          if (result.prefixes.isNotEmpty) {
            files = await _exploreDirectories(result);
          } else if (result.items.isNotEmpty) {
            files = await _getFilesFrom(result);
          } else {
            return [];
          }
      
          return files;
        }
      
        /// Gets the download URL of every file with their [refs].
        static Future<List<String>> _getDownloadLinks(List<Reference> refs) async {
          return Future.wait(refs.map((ref) => ref.getDownloadURL()).toList());
        }
      }
      

      【讨论】:

        猜你喜欢
        • 2019-10-09
        • 2020-10-30
        • 1970-01-01
        • 2011-11-23
        • 2022-11-30
        • 1970-01-01
        • 2022-10-14
        • 1970-01-01
        • 2020-09-25
        相关资源
        最近更新 更多