使用 Pickers 使用 Flutter Web 将照片上传到 Firebase 存储时出错

Posted

技术标签:

【中文标题】使用 Pickers 使用 Flutter Web 将照片上传到 Firebase 存储时出错【英文标题】:Error uploading a photo to Firebase storage with Flutter Web using Pickers 【发布时间】:2021-03-19 22:17:16 【问题描述】:

我readFirebase storage 现在与 Flutter web 兼容。 我有这个代码,我可以用我的 android 版本上传照片,但我在 web.xml 中不断收到这个错误。 putfile() 触发错误:

Error: Unsupported operation: Platform._operatingSystem

我的上传方法如下:

  uploadImage() async 
    final _picker = ImagePicker();
    PickedFile image;
    if(kIsWeb)
      image = await _picker.getImage(source: ImageSource.gallery);
      var file = File(image.path);
      if (image != null)
      
        var snapshot = await _storage.ref()
            .child('descriptionimages/'+widget.activity.id)
            .putFile(file);
        var downloadUrl = await snapshot.ref.getDownloadURL();
      
      else print('No Path Received');
    
  

这个问题也可能与我正在使用的image picker 有关。在自述文件中说:Note that on the web platform (kIsWeb == true), File is not available, so the path of the PickedFile will point to a network resource instead.

更新 我安装了这个FilePicker 并更改了代码使其如下所示:

  uploadImage() async 
    final _storage = FirebaseStorage.instance;
    PickedFile image;
    if(kIsWeb)
      FilePickerResult result = await FilePicker.platform.pickFiles();
      if (result != null)
      
        File file = File(result.files.single.path);
        var snapshot = await _storage.ref()
            .child('descriptionimages/'+widget.activity.id)
            .putFile(file);
        var downloadUrl = await snapshot.ref.getDownloadURL();
        setState(()
        
          widget.activity.image = downloadUrl;
          ActivityService().updateActivity(widget.activity);
        );
      
      else print('No Path Received');
    

不过,我在File file = File(result.files.single.path) 中遇到了另一个错误。路径为空,会导致错误。 It seems that this plugin has the path null.

有什么建议吗?我将继续研究支持网络路径的 Picker。

【问题讨论】:

你更新插件了吗? 你指的是哪一个?我有类似FlutterFire、same with image_picker 的版本。 【参考方案1】:

在 Web 中,您必须设置元数据并使用 putData 而不是 putFile:

final metadata = firebase_storage.SettableMetadata(
    contentType: 'image/jpeg',
    customMetadata: 'picked-file-path': file.path);

if (kIsWeb) 
  uploadTask = ref.putData(await file.readAsBytes(), metadata);
 else 
  uploadTask = ref.putFile(io.File(file.path), metadata);

你可以在https://pub.dev/packages/firebase_storage/example看到完整的例子

【讨论】:

【参考方案2】:

//这应该是正确的代码,快乐编码!

uploadImage() 异步

final _storage = FirebaseStorage.instance;
PickedFile image;
if(kIsWeb)
  FilePickerResult result = await FilePicker.platform.pickFiles();
  if (result != null)
  
    File file = File(result.files.single.bytes);
    var snapshot = await _storage.ref()
        .child('descriptionimages/'+widget.activity.id)
        .putData(file);
    var downloadUrl = await snapshot.ref.getDownloadURL();
    setState(()
    
      widget.activity.image = downloadUrl;
      ActivityService().updateActivity(widget.activity);
    );
  
  else print('No Path Received');

【讨论】:

你的解决方案看起来比我的更干净,干得好!【参考方案3】:

您不能使用 file_picker 在网络上使用路径,因为路径是假的,您必须使用字节来获取文件,然后在 firebase 存储上使用 putData。

最好的,

哈维尔·德克斯特

【讨论】:

【参考方案4】:

这些家伙 here 和 here 在几个月前就已经给出了答案(我的敬意)。

我的代码结果是这样的,它可以工作:

uploadImage() async 
    final _storage = FirebaseStorage.instance;
    final _picker = ImagePicker();
    PickedFile image;
    if(kIsWeb)
      image = await _picker.getImage(source: ImageSource.gallery);
      var bytes = await image.readAsBytes();
      if (image != null)
      
        var ref= _storage.ref();
        var snapshot = await ref.child('descriptionimages/'+widget.activity.id)
            .putData(bytes);
        var downloadUrl = await snapshot.ref.getDownloadURL();
        setState(()
        
          ...
        );
      
      else print('No Path Received');
    

【讨论】:

以上是关于使用 Pickers 使用 Flutter Web 将照片上传到 Firebase 存储时出错的主要内容,如果未能解决你的问题,请参考以下文章

Pickers(选择器)

Espresso 测试无法处理 Pickers

Pickers应用程序

在 Flutter Web 中使用 Flutter 移动包

flutter项目中添加web支持

Flutter - 无法在flutter web中使用动态链接