从firebase存储下载文件到Flatter

从firebase存储下载文件到Flatter,firebase,flutter,firebase-storage,Firebase,Flutter,Firebase Storage,我见过几个在firebase存储中上载文档的示例,但没有从firebase存储下载文件列表到Flatter的文档。 在FixBasic文档中,有很多关于Android、iOS、Web、C++等的FixBar存储文档,但是没有颤动。 特别是当我谈论视频的时候 VideoPlayerController videoPlayerController; @override void initState() { videoPlayerController = VideoPlayerCon

我见过几个在firebase存储中上载文档的示例,但没有从firebase存储下载文件列表到Flatter的文档。 在FixBasic文档中,有很多关于Android、iOS、Web、C++等的FixBar存储文档,但是没有颤动。 特别是当我谈论视频的时候

VideoPlayerController videoPlayerController;
  @override
  void initState() {

    videoPlayerController = VideoPlayerController.network('/* Download Url*/');
    super.initState();
  }

视频需要应用程序初始化中的Url要找到从Flatter上传和下载文件到云存储的示例,请查看FlatterFire库的Url

该过程主要包括获取下载URL,该URL为您提供对文件的只读访问:

final String url = await ref.getDownloadURL();
然后使用以下内容从该URL加载数据:

final http.Response downloadData = await http.get(url);
查看完整示例。

类UploadMultipleImageDemo扩展StatefulWidget{
class UploadMultipleImageDemo extends StatefulWidget {
  UploadMultipleImageDemo() : super();

  final String title = 'Firebase Storage';

  @override
  UploadMultipleImageDemoState createState() => UploadMultipleImageDemoState();
}

class UploadMultipleImageDemoState extends State<UploadMultipleImageDemo> {

  String _path;
  Map<String, String> _paths;
  String _extension;
  FileType _pickType = FileType.video;
  bool _multiPick = false;
  GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
  List<StorageUploadTask> _tasks = <StorageUploadTask>[];

  void openFileExplorer() async {
    try {
      _path = null;
      if (_multiPick) {
        _paths = await FilePicker.getMultiFilePath(
          type: FileType.video,  );
      } else {
        _path = await FilePicker.getFilePath(
          type: FileType.video, );
      }

      uploadToFirebase();
    } on PlatformException catch (e) {
      print("Unsupported operation" + e.toString());
    }
    if (!mounted) return;

  }

  uploadToFirebase() {
    if (_multiPick) {
      _paths.forEach((fileName, filePath) => {upload(fileName, filePath)});
    } else {
      String fileName = _path.split('/').last;
      String filePath = _path;
      upload(fileName, filePath);
    }
  }

  upload(fileName, filePath) {
    _extension = fileName.toString().split('.').last;
    StorageReference storageRef =
    FirebaseStorage.instance.ref().child(fileName);
    final StorageUploadTask uploadTask = storageRef.putFile(
      File(filePath),
      StorageMetadata(
        contentType: '$_pickType/$_extension',
      ),
    );
    setState(() {
      _tasks.add(uploadTask);
    });
  }
  String _bytesTransferred(StorageTaskSnapshot snapshot) {
    return '${snapshot.bytesTransferred}/${snapshot.totalByteCount}';
  }

  @override
  Widget build(BuildContext context) {
    final List<Widget> children = <Widget>[];
    _tasks.forEach((StorageUploadTask task) {
      final Widget tile = UploadTaskList(
        task: task,
        onDismissed: () => setState(() => _tasks.remove(task)),
        onDownload: () => downloadFile(task.lastSnapshot.ref),
      );
      children.add(tile);
    });

    return  MaterialApp(
      home: new Scaffold(
        key: _scaffoldKey,
        appBar: new AppBar(
          title: Text(widget.title),
        ),
        body: new Container(
          padding: EdgeInsets.all(20.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
              OutlineButton(
                onPressed: () => openFileExplorer(),
                child: new Text("Open file picker"),
              ),
              SizedBox(
                height: 20.0,
              ),


              Flexible(
                child: ListView(
                  children: children,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Future<void> downloadFile(StorageReference ref) async {
    final String url = await ref.getDownloadURL();
    final http.Response downloadData = await http.get(url);
    final Directory systemTempDir = Directory.systemTemp;
    final File tempFile = File('${systemTempDir.path}/tmp.jpg');
    if (tempFile.existsSync()) {
      await tempFile.delete();
    }
    await tempFile.create();
    final StorageFileDownloadTask task = ref.writeToFile(tempFile);
    final int byteCount = (await task.future).totalByteCount;
    var bodyBytes = downloadData.bodyBytes;
    final String name = await ref.getName();
    final String path = await ref.getPath();
    print(url);
    _scaffoldKey.currentState.showSnackBar(
      SnackBar(
        backgroundColor: Colors.white,
        content: Image.memory(
          bodyBytes,
          fit: BoxFit.fill,
        ),
      ),
    );
  }
}

class UploadTaskList extends StatelessWidget {
  const UploadTaskList(
      {Key key, this.task, this.onDismissed, this.onDownload})
      : super(key: key);

  final StorageUploadTask task;
  final VoidCallback onDismissed;
  final VoidCallback onDownload;

  String get status {
    String result;
    if (task.isComplete) {
      if (task.isSuccessful) {
        result = 'Complete';
      } else if (task.isCanceled) {
        result = 'Canceled';
      } else {
        result = 'Failed ERROR: ${task.lastSnapshot.error}';
      }
    } else if (task.isInProgress) {
      result = 'Uploading';
    } else if (task.isPaused) {
      result = 'Paused';
    }
    return result;
  }

  String _bytesTransferred(StorageTaskSnapshot snapshot) {
    return '${snapshot.bytesTransferred}/${snapshot.totalByteCount}';

  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<StorageTaskEvent>(
      stream: task.events,
      builder: (BuildContext context,
          AsyncSnapshot<StorageTaskEvent> asyncSnapshot) {
        Widget subtitle;
        Widget prog;
        Widget progtext;
        if (asyncSnapshot.hasData) {
          final StorageTaskEvent event = asyncSnapshot.data;
          final StorageTaskSnapshot snapshot = event.snapshot;
          subtitle = Text('$status: ${_bytesTransferred(snapshot)}');
          double _progress = event.snapshot.bytesTransferred.toDouble() / event.snapshot.totalByteCount.toDouble();
          prog = LinearProgressIndicator(
            value: _progress,
            backgroundColor: Colors.red,
          );
          progtext = Text('${(_progress * 100).toStringAsFixed(2)} %');



        } else {
          subtitle = const Text('Starting...');
        }
        return Dismissible(
          key: Key(task.hashCode.toString()),
          onDismissed: (_) => onDismissed(),
          child: ListTile(
            title: subtitle,
            // Text('Upload Task #${task.hashCode}'),

            subtitle: prog,
            trailing: Row(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                Offstage(
                  offstage: !task.isInProgress,
                  child: IconButton(
                    icon: const Icon(Icons.pause),
                    onPressed: () => task.pause(),
                  ),
                ),
                Offstage(
                  offstage: !task.isPaused,
                  child: IconButton(
                    icon: const Icon(Icons.file_upload),
                    onPressed: () => task.resume(),
                  ),
                ),
                Offstage(
                  offstage: task.isComplete,
                  child: IconButton(
                    icon: const Icon(Icons.cancel),
                    onPressed: () => task.cancel(),
                  ),
                ),
                Offstage(
                  offstage: !(task.isComplete && task.isSuccessful),
                  child: IconButton(
                    icon: const Icon(Icons.file_download),
                    onPressed: onDownload,
                  ),
                ),

              ],


            ),
          ),
        );
      },
    );
  }
}
UploadMultipleImageDemo():super(); 最终字符串标题='Firebase Storage'; @凌驾 UploadMultipleImageDemoState createState()=>UploadMultipleImageDemoState(); } 类UploadMultipleImageDemoState扩展状态{ 字符串路径; 映射路径; 字符串扩展; FileType _pickType=FileType.video; bool _multiPick=false; GlobalKey _scaffoldKey=GlobalKey(); 列表_任务=[]; void openFileExplorer()异步{ 试一试{ _path=null; 如果(_multiPick){ _路径=等待FilePicker.getMultiFilePath( 类型:FileType.video,); }否则{ _path=await FilePicker.getFilePath( 类型:FileType.video,); } 上传到Firebase(); }平台上异常捕获(e){ 打印(“不支持的操作”+e.toString()); } 如果(!已安装)返回; } 上传到firebase(){ 如果(_multiPick){ _forEach((文件名,文件路径)=>{upload(文件名,文件路径)}); }否则{ 字符串文件名=_path.split(“/”).last; 字符串文件路径=_路径; 上传(文件名、文件路径); } } 上载(文件名、文件路径){ _extension=fileName.toString().split('.').last; StorageReference-storageRef= FirebaseStorage.instance.ref().child(文件名); 最终StorageUploadTask uploadTask=storageRef.putFile( 文件(文件路径), 存储元数据( contentType:“$\u pickType/$\u扩展名”, ), ); 设置状态(){ _添加(上传任务); }); } 字符串\u ByTestTransferred(StorageTaskSnapshot快照){ 返回“${snapshot.bytesttransfered}/${snapshot.totalByteCount}”; } @凌驾 小部件构建(构建上下文){ 最终列表子项=[]; _tasks.forEach((StorageUploadTask任务){ 最终小部件磁贴=上传任务列表( 任务:任务, onDismissed:()=>设置状态(()=>_tasks.remove(task)), onDownload:()=>下载文件(task.lastSnapshot.ref), ); 添加(平铺); }); 返回材料PP( 家:新脚手架( 钥匙:_scaffoldKey, appBar:新的appBar( 标题:文本(widget.title), ), 主体:新容器( 填充:所有边缘设置(20.0), 子:列( crossAxisAlignment:crossAxisAlignment.start, mainAxisAlignment:mainAxisAlignment.start, 儿童:[ 大纲按钮( onPressed:()=>openFileExplorer(), 子项:新文本(“打开文件选择器”), ), 大小盒子( 身高:20.0, ), 灵活的( 子:ListView( 儿童:儿童,, ), ), ], ), ), ), ); } 未来下载文件(StorageReference ref)异步{ 最终字符串url=await ref.getDownloadURL(); final http.Response downloadData=wait http.get(url); 最终目录systemTempDir=Directory.systemTemp; final File tempFile=File('${systemTempDir.path}/tmp.jpg'); if(tempFile.existsSync()){ 等待tempFile.delete(); } 等待tempFile.create(); final-StorageFileDownloadTask任务=ref.writeToFile(tempFile); final int byteCount=(wait task.future).totalByteCount; var bodyBytes=downloadData.bodyBytes; 最终字符串名称=wait ref.getName(); 最终字符串路径=wait ref.getPath(); 打印(url); _scaffoldKey.currentState.showSnackBar( 小吃条( 背景颜色:Colors.white, 内容:Image.memory( 体字节, fit:BoxFit.fill, ), ), ); } } 类UploadTaskList扩展了无状态小部件{ 常量上载任务列表( {Key Key,this.task,this.onDismissed,this.onDownload}) :super(key:key); 最终StorageUploadTask任务; 最终作废; 最终空负荷; 字符串获取状态{ 字符串结果; if(task.isComplete){ 如果(任务成功){ 结果='完成'; }else if(task.isCanceled){ 结果='取消'; }否则{ 结果='失败的错误:${task.lastSnapshot.ERROR}'; } }else if(task.isInProgress){ 结果='上传'; }else if(task.isPaused){ 结果='暂停'; } 返回结果; } 字符串\u ByTestTransferred(StorageTaskSnapshot快照){ 返回“${snapshot.bytesttransfered}/${snapshot.totalByteCount}”; } @凌驾 小部件构建(构建上下文){ 返回流生成器( 流:task.events, 生成器:(BuildContext上下文, 异步快照(异步快照){ 小部件字幕; 小部件程序; 文本; if(asyncSnapshot.hasData){ 最终StorageTaskEvent事件=asyncSnapshot.data; 最终StorageTaskSnapshot快照=event.snapshot; subtitle=文本(“$status:${u bytesttransfered(snapshot)}”); double _progress=event.snapshot.bytesttransfered.toDouble()/event.snapshot.totalByteCount.toDouble(); prog=线性压缩机指示器(