如何将 Firebase 存储项存储到本地缓存以节省带宽成本?

How to store Firebase Storage Items to local cache to save bandwidth costs?

我注册了一个使用 Flutter 和 Firebase 的项目,但我遇到了带宽限制方面的问题。免费配额是每天 1gb,我有一个包含 100 张图像(和一些文件)的列表。

有没有一种方法可以通过在本地 phone 缓存中缓存这些文件来最小化带宽成本,从而不必在每次打开屏幕时都从数据库中获取项目?

是否有软件包或类似的东西可以做到这一点?

我想你可以用 cached network image

轻松做到

如果你想要更多的控制,我创建了一个简单的函数来完成这项工作,你可以根据你的需要进一步定制它:

import 'dart:typed_data';
import 'dart:io';
import 'package:http/http.dart' show get;

Future<File> getCachedImageFile(final String imageId) async {
  final Directory temp = await getTemporaryDirectory();
  final String fullPathName = '${temp.path}/images/$imageId';
  final File imageFile = File(fullPathName);
  if (imageId == null) return null;
  if (await imageFile.exists() == false) { // will guarantee that you don't make the API request (or just get image from url if unprotected)
    final String endpoint = 'http://www.mywebsiteorRESTapi.com/'
    String imgUrl = endpoint + imageId + '.png';
    var response = await get(imgUrl);
    try {
      await imageFile.create(recursive: true);
      if (response.bodyBytes != null)
        await imageFile.writeAsBytes(response.bodyBytes);
        return imageFile;
    } on Exception catch (exception) {
      throw 'could not write image $exception';
    }
  }
  return imageFile;
}

在你的 FutureBuilder 中:

future: getCachedImageFile('1VsSbB4Kh7Ab7spjQBA');

...

return Image.file(snapshot.data)

您可以使用CachedNetworkImage package来避免每次都下载图片。它使用起来很简单,你只需要将 URL 传递给 Widget:

CachedNetworkImage(
        imageUrl: "http://via.placeholder.com/350x150",
        placeholder: (context, url) => CircularProgressIndicator(),
        errorWidget: (context, url, error) => Icon(Icons.error),
     ),

要控制图像的缓存时间*,请确保在上传图像时将缓存 header 添加到图像中,以便正确缓存它们(如果您使用的是 flutter web,也会在浏览器中缓存) :

    final contentType = 'image/*'; 
    final cacheControl = 'public, max-age=31556926'; // seconds -- ie 31556926 == one year
    final uploadTask = reference.putData(
        image.data,
        SettableMetadata(
          cacheControl: cacheControl,
          contentType: contentType,
        ));

因此,请确保在上传图像时存储图像的 URL,并将 URL 传递给用户以获取图像,而不是直接从 FirebaseStorage 下载图像,以防万一正在这样做。

*如果没有可用的缓存 header,我相信包默认为 7 天,但我无法确认。