Flutter云存储缓存插件cached_firestorage的使用

发布于 1周前 作者 vueper 来自 Flutter

Flutter云存储缓存插件cached_firestorage的使用

简介

cached_firestorage 是一个用于管理 Firebase Storage 下载 URL 并缓存结果的 Flutter 工具。它提供了一个单例模式的 CachedFirestorage 类,可以通过 CachedFirestorage.instance 访问。默认的缓存时长为 360 分钟(6 小时),但你可以根据需要自定义。

使用方法

初始化和配置

  1. 设置缓存时长

    CachedFirestorage.instance.cacheTimeout = 30; // 设置缓存时长为 30 分钟
    
  2. 创建子路径(可选): 如果你希望将缓存分为多个子路径,可以在初始化时设置:

    CachedFirestorage.instance.setStorageKeys({'cachePathName': 'cachePathValue'});
    

API

getDownloadURL

getDownloadURL 是主要的 API,返回一个 Future<String>,用于获取 Firebase Storage 中文件的下载 URL,并将其缓存。如果文件不存在且未提供备用路径,则返回空字符串。

  • 参数
    • String mapKey:缓存条目的键。
    • String filePath:Firebase Storage 中的文件路径。
    • String? storageKey:子路径键(如果有)。
    • String? fallbackFilePath:备用文件路径,当第一次尝试失败时使用。

示例:

FutureBuilder<String>(
  future: CachedFirestorage.instance.getDownloadURL(
    mapKey: '1',
    filePath: '1.jpeg',
  ),
  builder: (_, snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
      return const CircularProgressIndicator.adaptive();
    } else if (snapshot.hasError) {
      return const Text('An error occurred');
    } else {
      return Image.network(
        snapshot.data!,
        height: 100,
      );
    }
  },
)

removeCacheEntry

removeCacheEntry 用于手动移除缓存条目,适用于需要在缓存过期前更新下载 URL 的情况。

  • 参数
    • String mapKey:要移除的缓存条目的键。
    • String? storageKey:子路径键(如果有)。

示例:

ElevatedButton(
  child: const Text('Remove cache + Change URL'),
  onPressed: () {
    setState(() {
      currentPic = currentPic == '2-1.jpeg' ? '2-2.jpeg' : '2-1.jpeg';
      CachedFirestorage.instance.removeCacheEntry(mapKey: '2');
    });
  },
)

Widgets

RemotePicture

RemotePicture 是一个内置的 widget,专门用于显示存储在 Firebase Storage 中的图片。它已经优化了图片的加载和缓存。

  • 参数
    • String imagePath:Firebase Storage 中的图片路径。
    • String mapKey:缓存条目的键。
    • bool useAvatarView = false:是否使用 AvatarView 显示图片。
    • String? storageKey:子路径键(如果有)。
    • String? placeholder:本地占位图路径。
    • double? avatarViewRadius:头像的半径(仅当 useAvatarView == true 时有效)。
    • BoxFit? fit:图片的填充方式(仅当 useAvatarView == false 时有效)。

示例:

const Row(
  mainAxisAlignment: MainAxisAlignment.center,
  children: [
    SizedBox(
      height: 100,
      child: RemotePicture(
        imagePath: '3.jpeg',
        mapKey: '3',
      ),
    ),
  ],
),

const Row(
  mainAxisAlignment: MainAxisAlignment.center,
  children: [
    RemotePicture(
      imagePath: 'avatar.jpeg',
      mapKey: 'avatar',
      useAvatarView: true,
      avatarViewRadius: 60,
      fit: BoxFit.cover,
      storageKey: 'pp',
    ),
  ],
)

完整示例代码

以下是一个完整的示例应用,展示了如何使用 cached_firestorage 插件来缓存和显示 Firebase Storage 中的图片。

import 'package:cached_firestorage/lib.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  // 设置缓存时长为 30 分钟
  CachedFirestorage.instance.cacheTimeout = 30;

  // 创建子路径
  CachedFirestorage.instance.setStorageKeys({'pp': 'pp'});

  runApp(const Demo());
}

class Demo extends StatelessWidget {
  const Demo({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Cached Firestorage Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  [@override](/user/override)
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String currentPic = '2-1.jpeg';

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Cached Firestorage DEMO'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Center(
          child: ListView(
            children: [
              const Text(
                'The standard way is using a FutureBuilder.\n'
                'All you have to do is providing the Firebase Storage path and a key of your choice.\n'
                'CachedFirestorage will fetch the download url the first time, '
                'and keep that in cache until the timer expires',
                textAlign: TextAlign.center,
              ),
              const SizedBox(height: 8),
              FutureBuilder<String>(
                future: CachedFirestorage.instance.getDownloadURL(
                  mapKey: '1',
                  filePath: '1.jpeg',
                ),
                builder: (_, snapshot) {
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return const CircularProgressIndicator.adaptive();
                  } else if (snapshot.hasError) {
                    return const Text('An error occurred');
                  } else {
                    return Image.network(
                      snapshot.data!,
                      height: 100,
                    );
                  }
                },
              ),
              const Divider(height: 50),
              const Text(
                'You can invalidate the cache for a specific key every time you want\n'
                'This could be useful if you need to update the url associated a specific key.',
                textAlign: TextAlign.center,
              ),
              const SizedBox(height: 8),
              FutureBuilder<String>(
                future: CachedFirestorage.instance.getDownloadURL(
                  mapKey: '2',
                  filePath: currentPic,
                ),
                builder: (_, snapshot) {
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return const CircularProgressIndicator.adaptive();
                  } else if (snapshot.hasError) {
                    return const Text('An error occurred');
                  } else {
                    return Image.network(
                      snapshot.data!,
                      height: 100,
                    );
                  }
                },
              ),
              const SizedBox(height: 8),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  ElevatedButton(
                    child: const Text(
                      'Change URL',
                      style: TextStyle(fontSize: 12),
                      textAlign: TextAlign.center,
                    ),
                    onPressed: () {
                      setState(() {
                        currentPic = currentPic == '2-1.jpeg' ? '2-2.jpeg' : '2-1.jpeg';
                      });
                    },
                  ),
                  const SizedBox(width: 5),
                  ElevatedButton(
                    child: const Text(
                      'Remove cache + Change URL',
                      style: TextStyle(fontSize: 12),
                      textAlign: TextAlign.center,
                    ),
                    onPressed: () {
                      setState(() {
                        currentPic = currentPic == '2-1.jpeg' ? '2-2.jpeg' : '2-1.jpeg';
                        CachedFirestorage.instance.removeCacheEntry(mapKey: '2');
                      });
                    },
                  ),
                ],
              ),
              const Divider(height: 50),
              const Text(
                'CachedFirestorage ships with a utility widget named RemotePicture,\n'
                'which is already optimized for fetching and displaying images stored'
                'in Firebase Storage',
                textAlign: TextAlign.center,
              ),
              const SizedBox(height: 8),
              const Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  SizedBox(
                    height: 100,
                    child: RemotePicture(
                      imagePath: '3.jpeg',
                      mapKey: '3',
                    ),
                  ),
                ],
              ),
              const Divider(height: 50),
              const Text(
                'You can also use it for an avatar',
                textAlign: TextAlign.center,
              ),
              const SizedBox(height: 8),
              const Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  RemotePicture(
                    imagePath: 'avatar.jpeg',
                    mapKey: 'avatar',
                    useAvatarView: true,
                    avatarViewRadius: 60,
                    fit: BoxFit.cover,
                    storageKey: 'pp',
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

更多关于Flutter云存储缓存插件cached_firestorage的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter云存储缓存插件cached_firestorage的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用cached_firestorage插件的示例代码。cached_firestorage是一个用于Flutter的插件,它结合了Firebase Storage和本地缓存功能,以便更高效地处理图像和其他文件。

首先,确保你已经在pubspec.yaml文件中添加了cached_firestorage依赖项:

dependencies:
  flutter:
    sdk: flutter
  cached_firestorage: ^最新版本号  # 请替换为实际的最新版本号
  firebase_storage: ^最新版本号  # 请替换为实际的最新版本号
  firebase_core: ^最新版本号  # Firebase核心库,用于初始化Firebase应用

然后,运行flutter pub get来安装这些依赖项。

接下来,配置Firebase。你需要在Firebase控制台中创建一个项目,并将生成的google-services.json文件(对于Android)和GoogleService-Info.plist文件(对于iOS)添加到你的项目中。

然后,在你的Flutter应用中进行以下设置:

  1. 初始化Firebase应用
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}
  1. 使用cached_firestorage插件
import 'package:flutter/material.dart';
import 'package:cached_firestorage/cached_firestorage.dart';
import 'package:firebase_storage/firebase_storage.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Cached Firestorage Example'),
        ),
        body: Center(
          child: CachedFireStorageExample(),
        ),
      ),
    );
  }
}

class CachedFireStorageExample extends StatefulWidget {
  @override
  _CachedFireStorageExampleState createState() => _CachedFireStorageExampleState();
}

class _CachedFireStorageExampleState extends State<CachedFireStorageExample> {
  String? imageUrl;

  @override
  void initState() {
    super.initState();
    _fetchAndCacheImage();
  }

  Future<void> _fetchAndCacheImage() async {
    // 创建Firebase Storage引用
    final storageRef = FirebaseStorage.instance.ref().child('path/to/your/image.jpg');

    // 创建CachedFireStorage实例
    final cachedStorage = CachedFireStorage(
      firebaseStorageRef: storageRef,
      cacheDirectory: 'cached_images',  // 缓存目录
      maxCacheSize: 100 * 1024 * 1024,  // 最大缓存大小(100MB)
    );

    // 获取缓存或下载图像
    final file = await cachedStorage.getFile();

    // 将文件路径转换为图像URL
    setUrlFromFile(file);
  }

  Future<void> setUrlFromFile(File file) async {
    final imageUrl = file.path;
    setState(() {
      this.imageUrl = imageUrl;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        imageUrl != null
            ? Image.file(File(imageUrl!))
            : CircularProgressIndicator(),
      ],
    );
  }
}

在上面的代码中,我们:

  1. 初始化了Firebase应用。
  2. 创建了一个Firebase Storage引用,指向你想要缓存的文件。
  3. 使用CachedFireStorage类来管理文件的缓存。
  4. 使用getFile方法获取文件(如果文件已经缓存,则直接从缓存中获取;否则,从Firebase Storage下载并缓存)。
  5. 将文件路径转换为图像URL并显示在屏幕上。

请注意,此示例假设你已经正确配置了Firebase项目,并且Firebase Storage中有可用的图像文件。根据你的实际需求,你可能需要调整路径和缓存设置。

回到顶部