Flutter web - 将图像文件上传到 Firebase 存储

JDE*_*E10 13 file-upload image-upload google-cloud-functions firebase-storage flutter-web

在 flutter web 上,我从计算机中选择一个图像文件并获取一个 File 图像对象。然后我想将它上传到 Firebase 存储。对于 Android 和 iOS 版本的应用程序,我使用了 Firebase Cloud Function 和 http 多部分请求。它有效,但对于该应用程序的网络版本则无效。所以,

如何直接或通过 Cloud Functions 将 html 图像文件上传到 Firebase 存储?

JDE*_*E10 20

最后我设法找到了解决这个问题的方法。为了实现这一点,我需要安装两个依赖项,firebaseUniversal_html。虽然很难找到解决方案,但它的实现其实很简单。这是我用来将 html 图像文件上传到 Firebase Storage 到“images”文件夹的函数代码:

import 'dart:async';
import 'package:universal_html/prefer_universal/html.dart' as html;
import 'package:firebase/firebase.dart' as fb;

Future<Uri> uploadImageFile(html.File image,
      {String imageName}) async {
    fb.StorageReference storageRef = fb.storage().ref('images/$imageName');
    fb.UploadTaskSnapshot uploadTaskSnapshot = await storageRef.put(image).future;
    
    Uri imageUri = await uploadTaskSnapshot.ref.getDownloadURL();
    return imageUri;
}

Run Code Online (Sandbox Code Playgroud)

我希望它可以帮助和我有同样需求的人。

  • 如何获取 html.File? (7认同)
  • 根据这个答案,对我有用的是使用 [image_picker_for_web](https://pub.dev/packages/image_picker_for_web) 来获取图像。然后将该图像转换为 base64 编码并使用 ```putString``` 而不是上面的 ```put```。有关 putString 的更多文档可以在[此处](https://firebase.google.com/docs/storage/web/upload-files)找到 (2认同)

Avi*_*Jha 20

结合了这么多帖子后,我做到了,它有效!

不,您只是不需要任何种类的 Universal_HTML 或其他 image_picker_web。只需坚持使用图像选择器(https://pub.dev/packages/image_picker)。并使用下面的代码,就像我用来将图像上传到 Firebase Storage 一样,它可以在 IOS、Android、Web 上运行,我希望您已经添加了 ios 和 android 的权限。让我们开始!

Import

import 'package:firebase_storage/firebase_storage.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart' as Path;
Run Code Online (Sandbox Code Playgroud)

Call this method when you want to open a file picker in any of the above platforms!

chooseImage() async {
PickedFile? pickedFile = await ImagePicker().getImage(
      source: ImageSource.gallery,
    );
}
Run Code Online (Sandbox Code Playgroud)

now you've file in pickedFile use kIsWeb to find out if it's web or not!

uploadImageToStorage(PickedFile? pickedFile) async {
if(kIsWeb){
Reference _reference = _firebaseStorage
        .ref()
        .child('images/${Path.basename(pickedFile!.path)}');
    await _reference
        .putData(
      await pickedFile!.readAsBytes(),
      SettableMetadata(contentType: 'image/jpeg'),
    )
        .whenComplete(() async {
      await _reference.getDownloadURL().then((value) {
        uploadedPhotoUrl = value;
      });
    });
 }else{
//write a code for android or ios
}

}
Run Code Online (Sandbox Code Playgroud)


Joe*_*ler 9

2022年的答案

TLDR:在上传之前使用cross_file包将文件转换为 XFile 。

选择图像

使用image_picker包选择图像。这适用于 Android、iOS 和 Web。

Future<String?> selectPicture(ImageSource source) async {
  XFile? image = await imagePicker.pickImage(
    source: source,
    maxHeight: 1000,
    maxWidth: 1000,
  );

  return image?.path;
}
Run Code Online (Sandbox Code Playgroud)

将 XFile 转换为 Uint8List

String path = selectPicture(ImageSource.gallery);
Uint8List imageData = await XFile(path).readAsBytes()
Run Code Online (Sandbox Code Playgroud)

将Uint8List上传到云存储

UploadTask uploadTask = storageReference.putData(imageData);
Run Code Online (Sandbox Code Playgroud)


小智 5

这是适用于我上传图像的完整片段: 对我 html.File不起作用,文件已上传但您将Error loading preview在 firebase 存储中看到,因此只需直接传递字节对我有用。

要显示可以mediaInfo.bytes与支持字节的小部件一起使用的图像,例如FadeInImage您可以使用MemoryImage(mediaInfo.bytes)Image.memory(mediaInfo.bytes)

使用的包:

  1. 火力基地
  2. image_picker_web
  3. 小路
  4. mime_type
    Future<MediaInfo> imagePicker() async {    
        MediaInfo mediaInfo = await ImagePickerWeb.getImageInfo;
        return mediaInfo;
     }
     
     Future<Uri> uploadFile(
          MediaInfo mediaInfo, String ref, String fileName) async {
        try {
          String mimeType = mime(Path.basename(mediaInfo.fileName));

          // html.File mediaFile =
          //     new html.File(mediaInfo.data, mediaInfo.fileName, {'type': mimeType}); 
          final String extension = extensionFromMime(mimeType);

          var metadata = fb.UploadMetadata(
            contentType: mimeType,
          );

          fb.StorageReference storageReference =
              fb.storage().ref(ref).child(fileName + ".$extension");

          fb.UploadTaskSnapshot uploadTaskSnapshot =
              await storageReference.put(mediaInfo.data, metadata).future;

          Uri imageUri = await uploadTaskSnapshot.ref.getDownloadURL();
          print("download url $imageUri");
          return imageUri;
        } catch (e) {
          print("File Upload Error $e");
          return null;
        }
      }

Run Code Online (Sandbox Code Playgroud)