Flutter - 将图像上传到 Firebase 存储
Posted
技术标签:
【中文标题】Flutter - 将图像上传到 Firebase 存储【英文标题】:Flutter - Upload Image to Firebase Storage 【发布时间】:2019-01-22 06:39:27 【问题描述】:我从 Firebase 存储中获取图像,用相机拍照,或者从库中挑选一张。当其中一个完成后,我有一个存储Image
的类,以便我可以在需要时使用它。
现在我需要将此图片上传到 Firebase 存储(修改或新的,没关系)。 Firebase 允许我使用以下选项之一:putData
或 putFile
,每个都需要一个 Uint8List
或 File
。
如何获取我的Image
并从中获取File
或Uint8List
进行上传?
--
另外,为了解决这个问题,当我从 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存储然后将其写入firestore
Flutter web - 无法将图像上传到 Firebase 存储