【发布时间】:2021-05-27 00:42:02
【问题描述】:
我注册了一个使用 Flutter 和 Firebase 的项目,但遇到了带宽限制问题。免费配额是每天 1gb,我有一个包含 100 个图像(和一些文件)的列表。
有没有办法通过在本地手机缓存中缓存这些文件来最小化带宽成本,而不必每次打开屏幕时都从数据库中获取项目?
有没有一个包或类似的东西可以做到这一点?
【问题讨论】:
标签: firebase flutter dart caching firebase-storage
我注册了一个使用 Flutter 和 Firebase 的项目,但遇到了带宽限制问题。免费配额是每天 1gb,我有一个包含 100 个图像(和一些文件)的列表。
有没有办法通过在本地手机缓存中缓存这些文件来最小化带宽成本,而不必每次打开屏幕时都从数据库中获取项目?
有没有一个包或类似的东西可以做到这一点?
【问题讨论】:
标签: firebase flutter dart caching firebase-storage
我认为你可以通过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)
【讨论】:
你可以使用CachedNetworkImagepackage来避免每次都下载图片。它使用简单,您只需将 URL 传递给 Widget:
CachedNetworkImage(
imageUrl: "http://via.placeholder.com/350x150",
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
),
要控制图片的缓存时间*,请确保在上传图片时将缓存标头添加到图片中,以便正确缓存(如果您使用的是 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 下载图片,以防万一。
*如果没有可用的缓存头但我无法确认,我相信包默认为 7 天。
【讨论】:
FirebaseStorage.instance.ref().child(path).getDownloadURL(); 是否已经触发“读取”配额?