flutter 将多个图像上传到 firebase 存储,然后将 url 保存到 firestore

问题描述 投票:0回答:1

我想将多个图像上传到 Firebase 存储。但是,使用 image_picker 选取的图像并不是一次全部选取,而是一张一张地选取,因为它们是应该转到 Firestore 中特定字段的特定文档的图片。

How images are uploaded

我知道如何将单个文档上传到存储并使用以下代码检索 firestore 中的 url:

File? image;
String? imageUrl = "";
Future<File> customCompressed(
      {required File imagePathToCompress,
      quality = 100,
      percentage = 10}) async {
    var path = await FlutterNativeImage.compressImage(
        imagePathToCompress.absolute.path,
        quality: 100,
        percentage: 60);
    return path;
  }

  Future<File?> pickImage(BuildContext context) async {
    File? image;
    try {
      final pickedImage =
          await ImagePicker().pickImage(source: ImageSource.camera);
      if (pickedImage != null) {
        image = File(pickedImage.path);
        File compressedImage =
            await customCompressed(imagePathToCompress: image);
        setState(() {
          image = compressedImage;
        });
      }
    } catch (e) {
     print(e);
    }

    return image;
  }

  void selectImage() async {
    image = await pickImage(context);
  }

  upload() async {
    final uid = FirebaseAuth.instance.currentUser!.uid;
    var imageFile = File(image!.path);
    FirebaseStorage storage = FirebaseStorage.instance;
    Reference ref =
        storage.ref().child(childName).child(uid);
    UploadTask uploadTask = ref.putFile(imageFile);
    await uploadTask.whenComplete(() async {
      var url = await ref.getDownloadURL();
      imageUrl = url.toString();
    }).catchError((onError) {
      return onError;
    });
FirebaseFirestore.instance.collection(collectionName).doc(uid).set({
  "Url": imageUrl!,});
  }

如何将多个图像(在本例中为三个图像)上传到存储,然后将每个图像 URL 上传到 Firestore,其中每个图像都包含特定文件。举个例子吧

FirebaseFirestore.instance.collection(collectionName)
.doc(uid)
.set({
"front_view_of_vehicle": imageUrl1!,
"Vehicle_doc": imageUrl2!,
"Driver_license": imageUrl3!,
});

我已经尝试过此操作,但图像文件未在 Firestore 中创建

File? image;
  File? image2;
  File? image3;

  String? imageUrl = "";
  String? imageUrl2 = "";
  String? imageUrl3 = "";

  Future<File> customCompressed(
      {required File imagePathToCompress,
      quality = 100,
      percentage = 10}) async {
    var path = await FlutterNativeImage.compressImage(
        imagePathToCompress.absolute.path,
        quality: 100,
        percentage: 60);
    return path;
  }

  Future<File?> pickImage(BuildContext context) async {
    File? image;
    try {
      final pickedImage =
          await ImagePicker().pickImage(source: ImageSource.gallery);
      if (pickedImage != null) {
        image = File(pickedImage.path);
        File compressedImage =
            await customCompressed(imagePathToCompress: image);

        setState(() {
          image = compressedImage;
        });
      }
    } catch (e) {
      Utils().awesomeDialogError(context, e.toString(), widget.failedString);
    }

    return image;
  }

  Future<File?> pickImage2(BuildContext context) async {
    File? image2;
    try {
      final pickedImage2 =
          await ImagePicker().pickImage(source: ImageSource.gallery);
      if (pickedImage2 != null) {
        image2 = File(pickedImage2.path);
        File compressedImage2 =
            await customCompressed(imagePathToCompress: image2);

        // UserInfos().customCompressed(imagePathToCompress: image);

        setState(() {
          image2 = compressedImage2;
        });
      }
    } catch (e) {
      // ignore: use_build_context_synchronously
      Utils().awesomeDialogError(context, e.toString(), widget.failedString);
    }

    return image2;
  }

  Future<File?> pickImage3(BuildContext context) async {
    File? image3;
    try {
      final pickedImage3 =
          await ImagePicker().pickImage(source: ImageSource.gallery);
      if (pickedImage3 != null) {
        image3 = File(pickedImage3.path);
        File compressedImage3 =
            await customCompressed(imagePathToCompress: image3);

        // UserInfos().customCompressed(imagePathToCompress: image);

        setState(() {
          image3 = compressedImage3;
        });
      }
    } catch (e) {
      // ignore: use_build_context_synchronously
      Utils().awesomeDialogError(context, e.toString(), widget.failedString);
    }

    return image3;
  }

  void selectImage() async {
    image = await pickImage(context);
  }

  void selectImage2() async {
    image2 = await pickImage2(context);
  }

  void selectImage3() async {
    image3 = await pickImage3(context);
  }

  upload() async {
    final uid = FirebaseAuth.instance.currentUser!.uid;

    var imageFile = File(image!.path);
    var imageFile2 = File(image2!.path);
    var imageFile3 = File(image3!.path);

    FirebaseStorage storage = FirebaseStorage.instance;
    Reference ref = storage
        .ref()
        .child(childName)
        .child(uid)
        .child(childName)
        .child(uid);

    UploadTask uploadTask = ref.putFile(imageFile);
    UploadTask uploadTask2 = ref.putFile(imageFile2);
    UploadTask uploadTask3 = ref.putFile(imageFile3);
    await uploadTask.whenComplete(() async {
      var url = await ref.getDownloadURL();
      imageUrl = url.toString();
    }).catchError((onError) {
      return onError;
    });
    await uploadTask2.whenComplete(() async {
      var url2 = await ref.getDownloadURL();
      imageUrl2 = url2.toString();
    }).catchError((onError) {
      return onError;
    });
    await uploadTask3.whenComplete(() async {
      var url3 = await ref.getDownloadURL();
      imageUrl3 = url3.toString();
    }).catchError((onError) {
      return onError;
    });
  }
flutter google-cloud-firestore google-cloud-storage
1个回答
0
投票

使用

await
whenComplete
,而不是同时使用。

这样,

upload
函数的主要代码就可以变成:

UploadTask uploadTask = ref.putFile(imageFile);
UploadTask uploadTask2 = ref.putFile(imageFile2);
UploadTask uploadTask3 = ref.putFile(imageFile3);

await uploadTask;
var url = await ref.getDownloadURL();
imageUrl = url.toString();
await uploadTask2
var url2 = await ref.getDownloadURL();
imageUrl2 = url2.toString();
await uploadTask3;
var url3 = await ref.getDownloadURL();
imageUrl3 = url3.toString();

// Write imageUrl, imageUrl2, and imageUrl3 to Firestore here

然后您可以在上传结束时将 URL 写入 Firestore。


上面按顺序上传并获取下载网址。您可以通过并行启动它们来加快速度,然后[等待所有 future](Future.wait() for multiple futures 完成)。

© www.soinside.com 2019 - 2024. All rights reserved.