You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter对接Firebase Storage:如何实现带下载通知的文件下载

问题根因解释
  • 你当前的代码是将文件下载到了应用的私有沙盒目录,Android系统不会为应用私有目录的文件下载自动触发系统通知,所以你看不到下载提示,下载本身大概率是正常完成的,可以通过打印downloadToFile.exists()的返回值验证。
  • 控制台的W/NetworkRequest( 9067): No App Check token for request.警告仅表示你未启用Firebase App Check服务,只要你的Storage安全规则没有强制校验App Check令牌,就不会影响下载功能,可忽略。
官方推荐解决方案

分两种适配场景:

场景1:文件仅需本应用访问,保留私有目录存储

使用Flutter官方维护的flutter_local_notifications包自主实现下载进度通知,是目前最稳定的方案,实现步骤如下:

  • 第一步:在AndroidManifest.xml中添加通知权限声明(适配Android13+)
  • 第二步:初始化通知插件,在下载的不同阶段更新通知内容
  • 参考实现代码:
// 全局初始化通知插件,建议放在应用启动阶段
final FlutterLocalNotificationsPlugin localNotificationsPlugin = FlutterLocalNotificationsPlugin();
const AndroidInitializationSettings androidInitSettings = AndroidInitializationSettings('@mipmap/ic_launcher');
const InitializationSettings initSettings = InitializationSettings(android: androidInitSettings);
await localNotificationsPlugin.initialize(initSettings);

// 修改后的onTap逻辑
onTap: () async {
  // 申请通知权限(Android 13及以上版本必需)
  if (Platform.isAndroid) {
    final androidPlugin = localNotificationsPlugin.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>();
    await androidPlugin?.requestNotificationsPermission();
  }

  final appDocDir = await getApplicationDocumentsDirectory();
  final targetFile = File('${appDocDir.path}/download-document.pdf');

  // 发送下载开始通知
  await localNotificationsPlugin.show(
    1001, // 通知唯一ID
    'PDF下载中',
    '准备下载文件',
    const NotificationDetails(
      android: AndroidNotificationDetails(
        'file_download',
        '文件下载',
        channelDescription: '展示文件下载进度',
        showProgress: true,
        maxProgress: 100,
        progress: 0,
        importance: Importance.low,
      )
    )
  );

  // 启动带进度监听的下载任务
  final downloadTask = FirebaseStorage.instance
      .ref('/myFolder/myUser/myFile.pdf')
      .writeToFile(targetFile);

  downloadTask.snapshotEvents.listen((snapshot) async {
    final progress = (snapshot.bytesTransferred / snapshot.totalBytes * 100).round();
    switch(snapshot.state) {
      case TaskState.running:
        // 更新进度通知
        await localNotificationsPlugin.show(
          1001,
          'PDF下载中',
          '已完成$progress%',
          NotificationDetails(
            android: AndroidNotificationDetails(
              'file_download',
              '文件下载',
              channelDescription: '展示文件下载进度',
              showProgress: true,
              maxProgress: 100,
              progress: progress,
              importance: Importance.low,
            )
          )
        );
        break;
      case TaskState.success:
        // 发送下载完成通知
        await localNotificationsPlugin.show(
          1001,
          '下载完成',
          'PDF文件已保存到本地',
          const NotificationDetails(
            android: AndroidNotificationDetails(
              'file_download',
              '文件下载',
              channelDescription: '展示文件下载进度',
              showProgress: false,
              importance: Importance.high,
            )
          )
        );
        break;
      case TaskState.error:
        // 发送下载失败通知
        await localNotificationsPlugin.show(
          1001,
          '下载失败',
          '请检查网络后重试',
          const NotificationDetails(
            android: AndroidNotificationDetails(
              'file_download',
              '文件下载',
              channelDescription: '展示文件下载进度',
              showProgress: false,
              importance: Importance.high,
            )
          )
        );
        break;
      default:
        break;
    }
  });
}

场景2:文件需对用户可见,保存到公共下载目录

直接调用系统下载管理器处理下载,系统会自动展示下载通知、存到公共下载目录,无需自己实现通知逻辑,步骤如下:

  • 第一步:调用Storage ref的getDownloadURL()方法获取文件的公网直链
  • 第二步:将直链传给系统下载管理器,触发系统下载流程即可
其他说明

如果需要消除App Check相关警告,可在Firebase控制台开启App Check服务,按配置流程完成客户端集成即可。

内容的提问来源于stack exchange,提问作者venir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 07:36:03