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
相关产品推荐
相关产品推荐

