Flutter Web 上传到 Firestore

Job*_*yNZ 13 firebase flutter google-cloud-firestore flutter-web

我在使用 Flutter web 并将图像上传到 Firestore 时遇到问题。我很确定问题出在图像选择器中,因为普通(移动)图像选择器不适用于网络。普通图像选择器返回一个文件,但替代image_picker_web返回一个图像,该图像在上传时被拒绝,因为它需要一个Future<File>.

image_picker_web有一种替代方法可以返回Uint8List我使用过的 a,然后转换为Filevia dart:html- 并正常上传,但图像已损坏且无法查看。

这是我所做的:

按下按钮 - 选择图像Uint8List> 转换为Image,存储在内存中并在屏幕上显示

                  onPressed: () async {
                    //Upload Image as Uint8List
                    imageBytes = await ImagePickerWeb.getImage(asUint8List: true);
                    //Convert Uint8List to Image
                    _image = Image.memory(imageBytes);
                    //Show new image on screen
                    setBottomSheetState(() {
                      image = _image;
                    });
                  },
Run Code Online (Sandbox Code Playgroud)

转换Uint8List为Fileusingdart:html File和 name as users UID.png (PNG Uploaded)

 imageFile = html.File(imageBytes, '${user.uid}.png');
Run Code Online (Sandbox Code Playgroud)

使用方法上传文件

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

String url;

  Future<String> uploadProfilePhoto(html.File image, {String imageName}) async {

    try {
      //Upload Profile Photo
      fb.StorageReference _storage = fb.storage().ref('profilephotos/$imageName.png');
      fb.UploadTaskSnapshot uploadTaskSnapshot = await _storage.put(image).future;
      // Wait until the file is uploaded then store the download url
      var imageUri = await uploadTaskSnapshot.ref.getDownloadURL();
      url = imageUri.toString();

    } catch (e) {
      print(e);
    }
    return url;
  }
Run Code Online (Sandbox Code Playgroud)

调用方法

location = await uploadProfilePhoto(imageFile, imageName: '${user.uid}');
Run Code Online (Sandbox Code Playgroud)

将包括位置在内的数据添加到 Firebase 数据库

//Pass new user ID through to users Collection to link UserData to this user
await AdminUserData(uid: user.uid).updateAdminUserData(name: userName, email: userEmail, profilephoto: location);
Run Code Online (Sandbox Code Playgroud)

一切正常,只是图像似乎已损坏,它也以几乎两倍的文件大小返回,这显然意味着文件不会作为图像返回..

Fri*_*yan 1

我没有尝试过你提到的替代方案,但下面的方法之前在 Flutter Web 和 Firebase 上对我有用。uploadInput 的事件侦听器适用于大多数平台。关于 document.body.append 的最后一部分将确保它也适用于 Mobile safari。

  Future<void> _setImage() async {
    final completer = Completer<String>();
    InputElement uploadInput = FileUploadInputElement();
    uploadInput.multiple = false;
    uploadInput.accept = 'image/*';
    uploadInput.click();
    
    uploadInput.addEventListener('change', (e) async {
      // read file content as dataURL
      final files = uploadInput.files;
      Iterable<Future<String>> resultsFutures = files.map((file) {
        final reader = FileReader();
        reader.readAsDataUrl(file);
        reader.onError.listen((error) => completer.completeError(error));
        return reader.onLoad.first.then((_) => reader.result as String);
      });

      final results = await Future.wait(resultsFutures);
      completer.complete(results[0]);
    });

    
    document.body.append(uploadInput);
    final String image = await completer.future;

    widget.newImage = uploadInput.files[0];

    // Upload to Firebase
    uploadToFirebase(widget.newImage); // This is dart:html File

    uploadInput.remove();
  }
Run Code Online (Sandbox Code Playgroud)

然后上传到 Firebase Storage:

uploadToFirebase(String imageName, File file) async {
 Firebase.UploadTask task = storage.refFromURL('gs://.../images/' + imageName).put(file); 
}
Run Code Online (Sandbox Code Playgroud)