Flutter - 将图片上传至Firebase Storage

25

我从 Firebase Storage 获取图像,使用相机拍照或从库中选择一张图像。当其中之一完成时,我有一个存储 Image 的类,以便在需要时使用它。

现在我需要将此图像上传到 Firebase Storage(修改后或新的都可以)。Firebase 允许我使用以下之一:putDataputFile,每个选项需要一个 Uint8ListFile

我该如何对我的 Image 进行操作,以便获取要上传的 FileUint8List

--

作为解决方法,当我从 Firebase Storage 中检索图像时,我该如何获取其 File

无论哪种方式,最终都需要提供正确的数据类型才能上传图像,无论是在开始时还是结束时获取 File

11个回答

24

当你使用图像选择器选择一张图片时,它会返回一个File对象,你可以使用await关键字等待用户选择文件,然后将其作为File对象存储。以下是示例代码,展示如何从图像选择器中获取文件并将其上传到Firebase。

    FirebaseStorage _storage = FirebaseStorage.instance;

    Future<Uri> uploadPic() async {

    //Get the file from the image picker and store it 
    File image = await ImagePicker.pickImage(source: ImageSource.gallery);  

    //Create a reference to the location you want to upload to in firebase  
    StorageReference reference = _storage.ref().child("images/");

    //Upload the file to firebase 
    StorageUploadTask uploadTask = reference.putFile(file);

    // Waits till the file is uploaded then stores the download url 
    Uri location = (await uploadTask.future).downloadUrl;

    //returns the download url 
    return location;
   }

1
我认为这个答案不好,因为它没有明确解释如何将“Image”上传到Firebase Storage的概念。它看起来更像是一个实际应用程序中的代码片段。 - creativecreatorormaybenot
一个Image是一个文件,下面的示例演示了如何将文件上传到Firebase存储中。如果您想了解Firebase内部工作原理,建议您阅读文档 - Nash
答案提供了注释,使得归档变得容易。我相信这个答案已经足够了。 - S1r-Lanzelot
4
我知道这是一个老回答,但我只想确认一下它是否仍然有效。uploadTask 中不存在未来(future)。 - user3836415
3
上述方法已被弃用,现在您需要执行以下操作:https://dev59.com/tlIG5IYBdhLWcg3whQSH#64764390 - Peter Haddad

7

抱歉回复晚了,上面的答案有点旧,希望我的回答能对你有所帮助。以下代码示例将在以下依赖项上工作。

在问题中,它说如何在上传后检索它。您可以使用下载URL获取文件或图像,您可以下载它,或者将其显示在NetworkImage小部件上以向用户显示。我已经展示了如何获取下载URL。

pubspec.yaml

dependencies
    image_picker: ^0.6.5
    firebase_storage: ^3.1.5

Dart Code

//Creating a global Variable    
StorageReference storageReference = FirebaseStorage.instance.ref();
File _image;

void getImage(){
    _image = await ImagePicker.pickImage(source: ImageSource.gallery); 
}

void addImageToFirebase(){


    //CreateRefernce to path.
    StorageReference ref = storageReference.child("yourstorageLocation/");

    //StorageUpload task is used to put the data you want in storage
    //Make sure to get the image first before calling this method otherwise _image will be null.

    StorageUploadTask storageUploadTask = ref.child("image1.jpg").putFile(_image);

     if (storageUploadTask.isSuccessful || storageUploadTask.isComplete) {
          final String url = await ref.getDownloadURL();
          print("The download URL is " + url);
     } else if (storageUploadTask.isInProgress) {

          storageUploadTask.events.listen((event) {
          double percentage = 100 *(event.snapshot.bytesTransferred.toDouble() 
                               / event.snapshot.totalByteCount.toDouble());  
          print("THe percentage " + percentage.toString());
          });

          StorageTaskSnapshot storageTaskSnapshot =await storageUploadTask.onComplete;
          downloadUrl1 = await storageTaskSnapshot.ref.getDownloadURL();

          //Here you can get the download URL when the task has been completed.
          print("Download URL " + downloadUrl1.toString());

     } else{
          //Catch any cases here that might come up like canceled, interrupted 
     }

}

6

想要选择图片(从相册、相机等中),你可以使用图片选择器 package

然后获取文件形式的图片,就像这样:

//Get the file from the image picker and store it
final pickedFile = await picker.getImage(source: ImageSource.camera);

  File image;
  if (pickedFile != null) {
    image = File(pickedFile.path);
  } else {
    print('No image selected.');
    return;
  }

然后检测您想要保存此文件图像的参考文献

FirebaseStorage storage = FirebaseStorage.instance;
//Create a reference to the location you want to upload to in firebase
StorageReference reference = storage.ref().child("profileImages/myImageUid");

最后开始上传并等待完成,然后获取图像的URL。

//Upload the file to firebase
        StorageUploadTask uploadTask = reference.putFile(image);
    
        StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
    
        // Waits till the file is uploaded then stores the download url
        String url = await taskSnapshot.ref.getDownloadURL();
    

完整代码

FirebaseStorage storage = FirebaseStorage.instance;

    File image;
    try {
      //Get the file from the image picker and store it
      image = await ImagePicker.pickImage(source: ImageSource.gallery);

    } on PlatformException catch (e) {
      //PlatformException is thrown with code : this happen when user back with don't
      //selected image or not approve permission so stop method here 
      // check e.code to know what type is happen
      return;
    }

    //Create a reference to the location you want to upload to in firebase
    StorageReference reference =
        storage.ref().child("profileImages/${user.id}");

    //Upload the file to firebase
    StorageUploadTask uploadTask = reference.putFile(image);

    StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;

    // Waits till the file is uploaded then stores the download url
    String url = await taskSnapshot.ref.getDownloadURL();

4

同时,有一个库可以帮助您...

  1. 选择
  2. 裁剪、压缩
  3. 将图片上传至Firebase存储。

该库名为firebase_picture_uploader,可以像这样使用(节选自源代码):

new PictureUploadWidget(
  onPicturesChange: profilePictureCallback,
  initialImages: _profilePictures,
  settings: PictureUploadSettings(onErrorFunction: onErrorCallback),
  buttonStyle: const PictureUploadButtonStyle(),
  buttonText: 'Upload Picture',
  enabled: true,
)

Firebase图片上传示例:

Firebase图片上传示例


2
  ImagePicker imagePicker = ImagePicker();
      File file;
      String imageUrl;

// 图片选择器

  Future pickImageCamera() async {
    var image = await imagePicker.pickImage(source: ImageSource.camera);
    if (image != null) {
      setState(() {
        file = File(image.path);
      });
    }
  }

// 将选定的图像上传到FireStore

  uploadProfileImage() async {
    Reference reference = FirebaseStorage.instance
        .ref()
        .child('profileImage/${Path.basename(file.path)}');
    UploadTask uploadTask = reference.putFile(file);
    TaskSnapshot snapshot = await uploadTask;
    imageUrl = await snapshot.ref.getDownloadURL();
    print(imageUrl);
  }

2
当你从相册或相机选择图片时,只需使用下面提到的函数获取带有扩展名的文件名。最初的回答:

当您从相册或相机选择图像时,只需使用以下函数获取带有扩展名的文件名:

basename(image.path)

将文件和文件路径传递给Firebase Storage引用,附上文件名即可上传,无需考虑文件扩展名。
所使用的库:
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart';
import 'package:firebase_storage/firebase_storage.dart';

代码:

upload() async {
   //pick image   use ImageSource.camera for accessing camera. 
   File image = await ImagePicker.pickImage(source: ImageSource.gallery);

   //basename() function will give you the filename
   String fileName = basename(image.path);

   //passing your path with the filename to Firebase Storage Reference
   StorageReference reference =
        FirebaseHelper.firebaseStorage().child("your_path/$fileName");

   //upload the file to Firebase Storage
   StorageUploadTask uploadTask = reference.putFile(image);

   //Snapshot of the uploading task
   StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
}

1
我认为这是最佳方法。 - Zeeshan Mehdi

1
如果您使用的是firebase_storage >= 5.0.0-dev.1,那么StorageReference类已被重命名为Reference。
我的意思是Firebase的新版本不再使用以下格式:
//将路径和文件名传递给Firebase Storage引用 StorageReference reference = FirebaseHelper.firebaseStorage().child("your_path/$fileName");
正确的格式应该是: Reference reference = FirebaseHelper.firebaseStorage().child("your_path/$fileName");

答案不明确,最好提供一些代码或更多信息。 - Marcel Hofgesang
我的意思是,Firebase的新版本不再使用以下格式:// 通过文件名将您的路径传递给Firebase Storage引用 StorageReference reference = FirebaseHelper.firebaseStorage().child("your_path/$fileName");正确的方式应该是: Reference reference = FirebaseHelper.firebaseStorage().child("your_path/$fileName"); - WagnerFreiria
不错,为什么不把它放进你的答案里呢? - Marcel Hofgesang

0

ImagePicker可以帮助我们从相册/相机中获取文件,并使用FirebaseStorage上传它。 getDownloadURL()方法可以给我们提供已上传到Firebase的下载链接。

Future uploadImageToFirebase(BuildContext context) async {
        final picker = ImagePicker();
        final pickedFile = await picker.getImage(source: ImageSource. gallery);
        File image = new File(pickedFile.path);

        var reference = FirebaseStorage.instance.ref().child('last_image/car5'); // Modify this path/string as your need
        StorageUploadTask uploadTask = reference.putFile(file);
        StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
        taskSnapshot.ref.getDownloadURL().then(
              (value) => print("Download URL: $value"),
            );
      }

0

回答晚了,但这可能会对某些人有所帮助。 以下是我获取图库中的图像并将其上传到Firebase的方法。希望您会喜欢这种方法。

XFile? image;
ImagePicker().pickImage(source: ImageSource.gallery,).then((value) {
        setState(() {
        image = value;
              });
  });
FirebaseStorage.instance.ref("desiredPathForImage/").putFile(File(image!.path))
 .then((TaskSnapshot taskSnapshot) {
  if (taskSnapshot.state == TaskState.success) {
      print("Image uploaded Successful");
      // Get Image URL Now
      taskSnapshot.ref.getDownloadURL().then(
      (imageURL) {
      print("Image Download URL is $imageURL");
      });
     } 
  else if (taskSnapshot.state == TaskState.running) {
      // Show Prgress indicator
      }
  else if (taskSnapshot.state == TaskState.error) {
      // Handle Error Here
      }
   });

0
  firebase_core: ^1.10.3
  firebase_analytics: ^9.0.0
  firebase_messaging: ^11.2.1
  firebase_storage: ^10.2.4
  image_picker: ^0.8.4+4

import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;


Future<void> uploadImageToFirebase(XFile? image) async {
Directory appDocDir = await getApplicationDocumentsDirectory();
String filePath = 'directoryName/${image?.path.split("/").last}';
File file = File(image?.path ?? "");
try {
  TaskSnapshot uploadTask = await firebase_storage.FirebaseStorage.instance
      .ref(filePath)
      .putFile(file);
  String? url = await uploadTask.ref.getDownloadURL();
  print("download url : $url");
  vm.pickedImages[index] = url;
} on FirebaseException catch (e) {
  // e.g, e.code == 'canceled'
}

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接