【问题标题】:In flutter, after uploading a file to firebase storage, how do I get the public URL?在颤振中,将文件上传到firebase存储后,如何获取公共URL?
【发布时间】:2021-08-12 07:55:13
【问题描述】:

我有这些要求:

  1. 我想将文件上传到 Firebase 存储。
  2. 我想存储这些文件的 URL 列表(在 firebase firestore 数据库中)。
  3. 我想使用存储规则限制查看这些文件。

将文件上传到 Firebase 存储非常简单。

  var uploadTask = await firebase_storage.FirebaseStorage.instance
      .ref(ref)
      .putFile(
      file,
      firebase_storage.SettableMetadata(
          customMetadata: _customMetaData(ownerId, readAccess)));
  var url = await _getUrl(uploadTask);

之后检索 url 以访问文件也很简单。

var url = await uploadTask.ref.getDownloadURL();

但是,这个 url 包含一个安全令牌,它基本上绕过了我设置的安全规则。任何拥有包含令牌的 url 的人都可以访问该文件。所以......我没有像这样检索网址,而是实现了这个:

var url = await _getUrl(uploadTask);

在哪里...

/*
 * When we retrieve the download url using getDownloadURL then this include security token
 * This makes the URL accessible for everybody, bypassing any security rule.
 * I'm assuming that by removing the token this url becomes a URL only accessible for
 * those who have access rights through the storage rules.
 */
static Future<String> _getUrl(firebase_storage.TaskSnapshot uploadTask) async {
  var url = await uploadTask.ref.getDownloadURL();
  var uri = Uri.parse(url);
  var newMap = Map<String, dynamic>.from(uri.queryParameters)..removeWhere((k, v) => k == 'token');
  var newUri = uri.replace(queryParameters: newMap);
  var newUrl = newUri.toString();
  return newUrl;
}

问题是:这是正确的方法吗?我很困惑为什么没有标准方法可以在没有令牌的情况下检索 url。我也很困惑为什么没有人问这个问题。那么:我错过了什么?

【问题讨论】:

    标签: firebase flutter firebase-storage


    【解决方案1】:

    我假设通过删除令牌,这个 url 变成了一个只有通过存储规则具有访问权限的人才能访问的 URL。

    这个假设是不正确的。下载 URL 是一个不透明的 URL,您无法对其进行有意义的更改。以您的方式更改它会使其不起作用。

    如果您只希望经过身份验证的用户能够访问您的文件,则应该为其生成下载 URL。

    如果您需要在不授予公共访问权限的情况下与其他用户共享有关文件的信息,您可以存储其路径而不是下载 URL。然后,这些用户可以通过构造一个Reference 来访问该文件,然后在该引用上调用getDatawriteToFile。与通过下载 URL 进行的访问不同,通过引用进行的访问受到您的规则的保护。

    【讨论】:

    • 感谢您的回答。但我相信我会重新考虑。我无法显示来自 Firebase 存储的图像或视频。特别是现有的视频库没有实现从内存播放。作为视频的位置,这些库接受文件路径或 url。无论如何,这让我想到了另一种解决方案:申请存储的规则也适用于保存 URL 的 Cloud Firestore 集合,所以我相信因此只有在他/她有权访问 URL 时才能访问。你同意吗?
    • 该 URL 可以与未经身份验证/未经授权的人员共享,他们仍然可以访问基础文件。如果在您的情况下这不是问题,那么下载 URL 的不可猜测的性质可能对您的用例来说足够安全。
    【解决方案2】:

    根据 Frank van Puffelen 的回答,我最终实现了以下内容。 Ref 是对您的 Firebase 存储映像的引用...

    class FbStorageImage extends StatefulWidget {
      final String ref;
      
      const FbStorageImage({Key? key, required this.ref, }) : super(key: key);
    
      @override
      State<StatefulWidget> createState() {
        return _FbStorageImageState();
      }
    }
    
    class _FbStorageImageState extends State<FbStorageImage> {
      Future<Uint8List?>? future;
    
      @override
      void initState() {
        future = firebase_storage.FirebaseStorage.instance.ref(widget.ref).getData();
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return FutureBuilder<Uint8List?>(
            future: future,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                if (snapshot.data != null) {
                  return Image.memory(snapshot.data!);
                } else {
                  return Image.asset("notfound.png");
                }
              }
              return Center(child: DelayedCircularProgressIndicator());
            });
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-03
      • 2020-04-15
      • 2017-09-24
      • 2021-04-07
      • 2021-09-08
      • 2019-10-29
      • 2016-10-09
      相关资源
      最近更新 更多