Flutter - 将图像上传到 Firebase 存储

Posted

技术标签:

【中文标题】Flutter - 将图像上传到 Firebase 存储【英文标题】:Flutter - Upload Image to Firebase Storage 【发布时间】:2019-01-22 06:39:27 【问题描述】:

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

现在我需要将此图片上传到 Firebase 存储(修改或新的,没关系)。 Firebase 允许我使用以下选项之一:putDataputFile,每个都需要一个 Uint8ListFile

如何获取我的Image 并从中获取FileUint8List 进行上传?

--

另外,为了解决这个问题,当我从 Firebase 存储中检索图像时,如何获得图像的 File

无论是哪种方式,都可以提供正确的数据类型来上传图片,无论是在开头还是结尾都获得File

【问题讨论】:

【参考方案1】:

当您使用图像选择器选择图像时,它会返回一个文件,您可以使用await 等待用户选择一个文件,然后将其存储为文件。下面是一些示例代码,说明如何从图像选择器获取文件并将其上传到 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;
   

【讨论】:

我认为这个答案不好,因为它没有具体解释将Image上传到Firebase Storage的概念。它看起来更像是来自实际应用程序的代码 sn-p。 图像是一个文件,示例演示了如何将文件上传到 Firebase 存储,如果您想了解 Firebase 的内部工作原理,建议您阅读documentation。 答案提供了可以轻松归档的 cmets。我相信这个答案就足够了。 我知道这是一个旧答案,但只是想检查这是否仍然有效。 uploadTask 上不存在未来。 上述方式已被弃用,现在您必须执行以下操作:***.com/a/64764390/7015400【参考方案2】:

要先选择图片(画廊、相机等),您可以使用图片选择器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");

最后开始上传,等到完成再获取网址图片

//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();

【讨论】:

【参考方案3】:

对不起,我的回答迟了,但上面的答案有点老了,希望我的回答对你有帮助。下面的代码示例将适用于以下依赖项。

关于这个问题,它说我在上传后如何检索它。您可以使用下载 URL 来获取文件或图像,您可以下载它,也可以将其显示在 NetworkImage 小部件上以将其显示给您的用户。我在下面展示了如何获取下载 URL。

pubspec.yaml

dependencies
    image_picker: ^0.6.5
    firebase_storage: ^3.1.5

飞镖代码

//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 
     


【讨论】:

【参考方案4】:

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

    选择 裁剪、压缩 正在上传 一张图片到 Firebase 存储。

该库名为firebase_picture_uploader,可以这样使用(摘自Source):

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

Firebase 图片上传器示例:

【讨论】:

【参考方案5】:

当您从图库或相机中挑选图像时

只需使用下面提到的函数来获取带有扩展名的文件名

basename(image.path)

然后将文件传递给firebase存储参考,并带有您要上传到的路径和文件名,您不必考虑文件的扩展名。

使用的库

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;

【讨论】:

我认为这是最好的方法【参考方案6】:

如果您使用的是 firebase_storage >= 5.0.0-dev.1,则 StorageReference 类已重命名为 Reference

我的意思是较新版本的 Firebase 不使用以下格式:

// 将带有文件名的路径传递给 Firebase 存储参考 StorageReference reference = FirebaseHelper.firebaseStorage (). Child ("your_path/ $ fileName");

正确的应该是: Reference reference = FirebaseHelper.firebaseStorage (). Child ("your_path / $ fileName");

【讨论】:

答案不清楚,最好提供一些代码或更多信息 我的意思是较新版本的 Firebase 不使用以下格式: // 将带有文件名的路径传递给 Firebase 存储参考 StorageReference 参考 = FirebaseHelper.firebaseStorage ()。 Child ("your_path / $ fileName"); 正确的应该是:Reference reference = FirebaseHelper.firebaseStorage ()。孩子 ("your_path / $ fileName"); 看起来不错,你为什么不把它放在你的答案中?【参考方案7】:
  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);
  

【讨论】:

【参考方案8】:

firebase_storage:^3.0.6, 图像选择器:^0.6.1 这两个库你一定会用到

之后获取图片

  Future getImage() async 
    var tempImage = await ImagePicker.pickImage(source: ImageSource.gallery);

    setState(() 
      sampleImage = tempImage;
     );
  

现在上传图片

Widget enableUpload() 
return Container(
  child: Column(
    children: <Widget>[
      Image.file(sampleImage, height: 300.0, width: 300.0),
      RaisedButton(
        elevation: 7.0,
        child: Text('Upload'),
        textColor: Colors.white,
        color: Colors.blue,
        onPressed: () 
          final StorageReference firebaseStorageRef =
              FirebaseStorage.instance.ref().child('myimage.jpg');
          final StorageUploadTask task =
              firebaseStorageRef.putFile(sampleImage);

        ,
      )
    ],
  ),
);

您可以在需要的地方使用此 enableUpload() 小部件。

【讨论】:

【参考方案9】:

ImagePicker 有助于从图库/相机中获取文件并使用 FirebaseStorage 上传。 getDownloadURL() 方法为我们提供了上传到 firebase 的下载 URL。

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"),
            );
      

【讨论】:

【参考方案10】:

很晚才回答。但这可能会对某人有所帮助。 这是我首先从图库中获取图片然后将图片上传到 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
      
   );

【讨论】:

【参考方案11】:
  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'

【讨论】:

以上是关于Flutter - 将图像上传到 Firebase 存储的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Flutter 将图像上传到 Firebase

Flutter将图像上传到firebase存储然后将其写入firestore

Flutter web - 无法将图像上传到 Firebase 存储

将图像从 Firebase 下载到 Flutter

Flutter Resize ImagePicker Image 在上传到firebase之前

使用flutter将多张图片上传到firestore并获取它的下载URL并将所有URL保存到firebase