如何在 Flutter 中缓存来自 Firebase 的图像?

Posted

技术标签:

【中文标题】如何在 Flutter 中缓存来自 Firebase 的图像?【英文标题】:How to cache images from Firebase in Flutter? 【发布时间】:2020-09-13 04:06:03 【问题描述】:

我正在尝试访问 Firebase 存储中的图像并将它们缓存在设备本地。

我当前的尝试使用flutter_cache_manager。文档指出:

最常见的文件服务将是 [HttpFileService],但也可以制作更专业的东西。例如,您可以从其他应用程序或本地存储中获取文件。

class HttpFileService implements FileService 
  http.Client _httpClient;
  HttpFileService(http.Client httpClient) 
    _httpClient = httpClient ?? http.Client();
  

  @override
  Future<FileServiceResponse> get(String url,
      Map<String, String> headers = const ) async 
    final req = http.Request('GET', Uri.parse(url));
    req.headers.addAll(headers);
    final httpResponse = await _httpClient.send(req);

return HttpGetResponse(httpResponse);

  

我已尝试扩展此类以处理 Firebase 的 URL

class FirebaseHttpFileService extends HttpFileService 
  @override
  Future<FileServiceResponse> get(String url, Map<String, String> headers = const ) async 

    var ref = FirebaseStorage.instance.ref().child(url);
    var _url = await ref.getDownloadURL() as String;

    return super.get(_url);
  

并使用来自GitHub repo 的模板扩展 BaseCacheManager,用我的新服务替换文件服务。

class FirebaseCacheManager extends BaseCacheManager 
  static const key = "firebaseCache";

  static FirebaseCacheManager _instance;

  factory FirebaseCacheManager() 
    if (_instance == null) 
      _instance = new FirebaseCacheManager._();
    
    return _instance;
  

  FirebaseCacheManager._() : super(key,
      maxAgeCacheObject: Duration(days: 7),
      maxNrOfCacheObjects: 20,
      fileService: FirebaseHttpFileService());

  Future<String> getFilePath() async 
    var directory = await getTemporaryDirectory();
    return p.join(directory.path, key);
  


但我收到以下错误:

setState() called after dispose(): _ImageState#50d41(lifecycle state: defunct, not mounted, stream: ImageStream#ac6d5(MultiFrameImageStreamCompleter#0c956, [2448×3264] @ 1.0x, 3 listeners), pixels: null, loadingProgress: null, frameNumber: null, wasSynchronouslyLoaded: false)

我可以在尝试检索文件之前处理 URL,但这会不必要地浪费时间。我也尝试过使用其他软件包,例如 Flutter Cache Image,但它似乎在短时间内使应用程序崩溃。

感谢您提供正确方向的任何指示!

【问题讨论】:

检查这个图片缓存***.com/a/61813058/3946958 @ravindra-kushwaha 谢谢,但我已经在使用 CachedNetworkImage。图片 URL 需要通过 Firebase 解析,即使它已经被缓存。这就是为什么我想在缓存管理器级别实现一些东西。 在您的示例中,您使用 URL 来表示 StorageReference ID? 【参考方案1】:

这个问题实际上与问题here 中的errorWidget 有关。 如果错误小部件在CachedNetworkImage 中被注释掉,代码就可以工作。

【讨论】:

您的代码在任何地方都有我可以使用的完整版本吗?我也有同样的要求。 这是你的吗:pub.dev/packages/flutter_cache_manager_firebase 在我开始之前,我可以使用 Firebase 存储引用作为缓存键吗? URL 可能会更改,因此我需要先尝试获取文件的缓存版本,然后再尝试通过 URL 下载,然后设置缓存。 您的 Firebase 缓存管理器工作正常。混淆使用 URL 表示存储路径,然后也用于实际的 HTTP 下载 URL。不过都很好。谢谢你。 @LeeProbert 这是我的,但我不管理那个 repo,它是 Baseflow,所以我知道它不再是最新的 FlutterFire 包。

以上是关于如何在 Flutter 中缓存来自 Firebase 的图像?的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:Google Maps 如何从 Firestore 设置图标

如何在设备 Flutter 中保存缓存

如何将 Flutter Bloc 与 Firebase 电话身份验证一起使用

如何在 Flutter 中缓存 Firebase 数据?

如何在 Flutter Firebase 中清除以前的用户缓存数据?

如何在flutter中访问和更改来自不同文件的变量