【问题标题】:Downloading Files from firebase storage to flutter将文件从 Firebase 存储下载到颤振
【发布时间】:2019-10-29 19:15:35
【问题描述】:

我已经看到了几个关于在 firebase 存储中上传文档的示例,但是没有从 firebase 存储中下载文件列表到 Flutter 的文档。 在 Firebase 文档上,有很多关于 Android、iOS、web、c++ 等的 firebase 存储的文档,但没有 Flutter。 特别是如果我谈论视频的

VideoPlayerController videoPlayerController;
  @override
  void initState() {

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

视频在app初始化时需要Url

【问题讨论】:

    标签: firebase flutter firebase-storage


    【解决方案1】:

    要查找从 Flutter 上传和下载文件到 Cloud Storage 的示例,请查看 FlutterFire 库 firebase_storageexample application

    该过程主要包括获取下载 URL,它使您可以只读访问文件:

    final String url = await ref.getDownloadURL();
    

    然后从该 URL 加载数据:

    final http.Response downloadData = await http.get(url);
    

    查看_downloadFile method 获取完整示例。

    【讨论】:

    • 如果你有一个视频播放器需要一个 URL,那么你应该能够将下载 URL 传递给它。
    • 对于flutter中播放的视频,它只取上面代码中提到的处于init()状态的Url,因为下载的Url是异步的,所以在init()里面是不接受的state 或其中不接受 await 关键字。
    • 因此您必须将视频 URL 存储在您的状态中,然后在 UI 重新呈现时将其传递给视频播放器。
    • Frank,我是 Flutter 新手,能否提供一些示例代码
    • 404 在这些链接上。
    【解决方案2】:
    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,
                      ),
                    ),
    
                  ],
    
    
                ),
              ),
            );
          },
        );
      }
    }
    

    【讨论】:

    • 感谢您发布代码 - 如果您有时间,请添加一些 cmets。
    猜你喜欢
    • 2021-04-07
    • 2017-08-22
    • 2017-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-07
    相关资源
    最近更新 更多