How to get Download URL from Firebase Storage in flutter - flutter

The Following Code is used to Upload any image from gallery/Camera to Firebase storage. I was successful in uploading the image to storage along with meta data. Now the problem is I am not able to get the download URL of the uploaded image. Tried a lot but didn't find any solution.
FirebaseStorage storage = FirebaseStorage.instance;
final picker = ImagePicker();
PickedFile pickedImage;
File imageFile;
Future<void> _upload(String inputSource) async {
try {
pickedImage = await picker.getImage(
source: inputSource == 'camera'
? ImageSource.camera
: ImageSource.gallery,
maxWidth: 1920);
final String fileName = path.basename(pickedImage.path);
imageFile = File(pickedImage.path);
try {
// Uploading the selected image with some custom meta data
await storage.ref(fileName).putFile(
imageFile,
SettableMetadata(
customMetadata: {
'uploaded_by': 'A bad guy',
'description': 'Some description...'
},
),
);
// Refresh the UI
setState(() {});
} on FirebaseException catch (error) {
print(error);
}
} catch (err) {
print(err);
}
}

Hope You're Doing Well …
You Can Try This Method To Get The URL Of The Image(Any File) From Firebase Storage To Firebase Store And Then You Can Retrieve Image .
class _UploadAdState extends State<UploadAdPage> {
final formKey = GlobalKey<FormState>();
File _myimage;
String imgUrl;
Future getImage1(File chosenimage) async {
PickedFile img =
await ImagePicker.platform.pickImage(source: ImageSource.gallery);
if (chosenimage == null) return null;
File selected = File(img.path);
setState(() {
_myimage = chosenimage;
});
}
// changing the firestore rules and deleteing if request.auth != null;
sendData() async {
// to upload the image to firebase storage
var storageimage = FirebaseStorage.instance.ref().child(_myimage.path);
UploadTask task1 = storageimage.putFile(_myimage);
// to get the url of the image from firebase storage
imgUrl1 = await (await task1).ref.getDownloadURL();
// you can save the url as a text in you firebase store collection now
}
}

I am using in my app this function. Pass image file and download with getDownloadUrl .
Future <String> _uploadphotofile(mFileImage) async {
final Reference storageReference = FirebaseStorage.instance.ref().child("products");
UploadTask uploadTask = storageReference.child("product_$productId.jpg").putFile(imgfile);
String url = await (await uploadTask).ref.getDownloadURL();
return url;
}

Related

ImageCropper use with Uint8List file -flutter

I'm using image_picker & ImageCropper packages. I want to save a user-given picture in firestore database. So, I use functions like this.
First, set File? _image;
Functions for cropping & picking
Future _pickImage(ImageSource source) async {
Navigator.of(context).pop();
try {
final image = await ImagePicker().pickImage(source: source);
if (image == null) return;
File? img = File(image.path);
img = await _cropImage(imageFile: img);
setState(() {
_image = img;
});
} on PlatformException catch (e) {
print(e);
Navigator.of(context).pop();
}
}
Future<File?> _cropImage({required File imageFile}) async {
CroppedFile? croppedImage =
await ImageCropper().cropImage(sourcePath: imageFile.path);
if (CroppedFile == null) return null;
return File(croppedImage!.path);
}
and use this to save data in firestore
Future<String> uploadImageToStorage(
File file,
) async {
file
Reference ref =
_storage.ref().child("profilePics").child(_auth.currentUser!.uid);
UploadTask uploadTask = ref.putData(file);
TaskSnapshot snap = await uploadTask;
String downloadUrl = await snap.ref.getDownloadURL();
return downloadUrl;
}
Above function not work for File type data, It support for Uint8List. So, What can I do for this?
Next problem is, I'm getting File type data with ImagePicker for profile picture. Is it not problem?
Try changing your _cropImage-Method to return XFile? like this:
Future<XFile?> _cropImage({required File imageFile}) async {
CroppedFile? croppedImage =
await ImageCropper().cropImage(sourcePath: imageFile.path);
if (CroppedFile == null) return null;
return XFile(croppedImage!.path);
}
You also have to change the paramter of uploadImageToStorage to XFile file. Then you can use file!.readAsBytes(); to get a Uint8List.
Future<String> uploadImageToStorage(
XFile file,
) async {
Reference ref =
_storage.ref().child("profilePics").child(_auth.currentUser!.uid);
final fileBytes = await file.readAsBytes();
UploadTask uploadTask = ref.putData(fileBytes);
TaskSnapshot snap = await uploadTask;
String downloadUrl = await snap.ref.getDownloadURL();
return downloadUrl;
}

How can I show first time that getting image from firebase storage in my app?

I define pick image and photoUrl variables:
File? image;
String? photoUrl;
This is my pick image method:
Future pickImage(ImageSource source) async {
try {
final image = await ImagePicker().pickImage(source: ImageSource.gallery);
if (image == null) return;
final imageTemporary = File(image.path);
setState(() {
this.image = imageTemporary;
});
} on PlatformException catch (e) {
print('Failed to pick image : $e');
}
}
This is my upload image function ı upload image with current user ids:
Future uploadFile() async {
final path = '${_auth.currentUser!.uid}.jpg';
final file = File(image!.path);
final ref = FirebaseStorage.instance
.ref()
.child('images/${_auth.currentUser!.uid}.jpg');
task = await ref.putFile(file);
//final url = await ref.getDownloadURL();
//print('Download URLLLLLLLLLLLLLLLLLLLLL : $url');
/*
I saved download image url to setstate method
setState(() {
photoUrl = url.toString();
});
*/
}
This is my download image and init state method, when I upload image to firebase storage first time, ı am getting no object exist at desired reference error, but after ı upload image then I try
to download image and I want to show in image.network it works, How can I fix this error when I try to upload and download first time without error ?
Future downloadImage() async {
final ref = FirebaseStorage.instance
.ref()
.child('images/${_auth.currentUser!.uid}.jpg');
final url = await ref.getDownloadURL();
print('Download URLLLLLLLLLLLLLLLLLLLLL : $url');
setState(() {
photoUrl = url.toString();
});
}
#override
initState() {
// TODO: implement initState
super.initState();
downloadImage();
}
This is my error:
and
this is my storage its empty :
The problem seems to be that you are trying to get the url before uploading the image, Here is what you can do :
uploadImage() async {
final _firebaseStorage = FirebaseStorage.instance;
final _imagePicker = ImagePicker();
PickedFile image;
//Check Permissions
await Permission.photos.request();
var permissionStatus = await Permission.photos.status;
if (permissionStatus.isGranted){
//Select Image
image = await _imagePicker.getImage(source: ImageSource.gallery);
var file = File(image.path);
if (image != null){
//Upload to Firebase
var snapshot = await _firebaseStorage.ref()
.child('images/imageName')
.putFile(file).onComplete;
var downloadUrl = await snapshot.ref.getDownloadURL();
setState(() {
imageUrl = downloadUrl;
// in here you can add your code to store the url in firebase database for example:
FirebaseDatabase.instance
.ref('users/$userId/imageUrl')
.set(imageUrl)
.then((_) {
// Data saved successfully!
})
.catchError((error) {
// The write failed...
});
});
} else {
print('No Image Path Received');
}
} else {
print('Permission not granted. Try Again with permission access');
}
source How to upload to Firebase Storage with Flutter
I hope this will be helpfull

Saving image permenantly after user upload it in flutter

In my flutter app, if the user is signing in for the first time, he will be directed to profile page where he gets to key in his personal details and upload his profile pic. now my issue is with the profile pic. First of all, Im using Image picker package.
Future pickImage(ImageSource source) async {
try {
final image = await ImagePicker().pickImage(
source: source);
if (image == null) return;
final UserImage = File(image.path);
setState(() => this.image = UserImage );
}on PlatformException catch (e){
Utils.showSnackBar(e.message);
}
}
But with this code alone, everytime the app gets restarted the image will be null. So I tried to upload the image to the Firebase Storage when the user picks an image and generate a url:
Future uploadImage () async {
FirebaseStorage storage = FirebaseStorage.instance;
Reference ref = storage.ref().child(userID.toString());
UploadTask uploadTask = ref.putFile(image!);
uploadTask.whenComplete(() async {
url = await ref.getDownloadURL(); }
).catchError((onError){
print(onError);
});
return url;
}
But again every time I restart the app, the url will be null.
What is the best way to save the image permenantly when the user signs in for the first time.
edit: I want to store the image locally so that the user doesnt need an internet connection to load the image everytime he open the app.
Your answers and responses are highly appreciated.
you need to get folder directory first
Future<String> getStorageDirectory() async {
if (Platform.isAndroid) {
return (await getExternalStorageDirectory()).path;
} else {
return (await getApplicationDocumentsDirectory()).path;
}
}
Add image in path
uploadImage() async{
String dir= getStorageDirectory();
File directory = new File("$dir");
if (directory.exists() != true) {
directory.create();
}
final image = await ImagePicker().pickImage(
source: source);
if (image == null) return;
final userImage = File(image.path);
var newFile = await userImage.writeAsBytes(/* image bytes*/);
await newFile.create();
}

upload image by flutter in firebase Storage

I try to upload an image on firebase storage and get the error.
Future selectImage(ImageSource source) async {
try {
XFile? xImage = await ImagePicker().pickImage(source: source);//getting picture from phone
if(xImage == null ) return 'there is no image';
final File file = File(xImage.path);
//final Image image = Image.file(File(xImage.path));
print(xImage.path);
Directory appDocDir = await getApplicationDocumentsDirectory();
String filePath = '${appDocDir.absolute}/file-to-upload.png';
print(filePath);
final storageRef = FirebaseStorage.instance.ref().child("UsersProfilePhoto/");
await storageRef.putFile(file);
} on FirebaseException catch (e) {
print(e.message);
}
}
Try like this.
Future selectImage(ImageSource source) async {
try {
ImagePicker imagePicker = ImagePicker();
XFile pickedFile = await imagePicker.pickImage(source: source, imageQuality: 80);
File imageFile = File(pickedFile.path);
if(imageFile == null ) return 'there is no image';
print(imageFile.path);
String fileName = DateTime.now().millisecondsSinceEpoch.toString();
final storageRef = FirebaseStorage.instance.ref().child("UsersProfilePhoto/");
await storageRef.putFile(imageFile);
} on FirebaseException catch (e) {
print(e.message);
}
}
Try this
import 'package:path/path.dart' as Path1;//for storing image path in firestore
DatabaseReference reference = FirebaseDatabase.instance.reference();
FirebaseStorage storage = FirebaseStorage.instance;
File? fileImage;
//call this function for picking image
pickedImage() async{
PickedFile? file = await ImagePicker().getImage(
source: ImageSource.camera,
maxHeight: 1000,
maxWidth: 1000
);
File image = file!.path;
setState((){
fileImage = image;
});
}
//call this function for storing image in firestore
_storeImage() async{
Reference storagerefrence = storage.ref().child('card_images/${Path1.basename(fileImage!.path)}');
TaskSnapshot uploadTask = await storagerefrence.putFile(fileImage!);
String url = await storagerefrence.getDownloadURL();//download url from firestore and add to firebase database
reference.child("image").push().set({
'image' : url
});
}

Upload image to Firebase Storage and show as Profile Image after login again

My problem is that, if I select or capture an image then it update and store to firebase but when I login again then the defualt image shows. below is the code for get image.
Future takePhoto(ImageSource source) async {
final pickedFile = await _picker.pickImage(
source: source
);
selectedImage = File(pickedFile!.path);
final _firebaseStorage = FirebaseStorage.instance;
var snapshot = await _firebaseStorage.ref()
.child('images/imageName')
.putFile(selectedImage!);
var downloadUrl = await snapshot.ref.getDownloadURL();
print("hi there is a print statement with url "+downloadUrl);
setState(() {
imageUrl = downloadUrl;
_imageFile = pickedFile;
});
}