How I get file url from firestore path in flutter - flutter

When upload audio file then I gave firestorage file path , it's uploading successfully but I want to get file URL in to logged user details in firestore that's also insert correctly in firestore but not file URL that is file path. How I get URL from file path.
//firestorage upload
Future<void> _onFileUploadButtonPressed() async {
FirebaseStorage firebaseStorage = FirebaseStorage.instance;
setState(() {
_isUploading = true;
});
try {
await firebaseStorage
.ref()
.child("${loggedInUser.uid}/records1")
.child(
_filePath.substring(_filePath.lastIndexOf('/'), _filePath.length))
.putFile(File(_filePath));
widget.onUploadComplete();
onsend();
} catch (error) {
print('Error occured while uplaoding to Firebase ${error.toString()}');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Error occured while uplaoding'),
),
);
} finally {
setState(() {
_isUploading = false;
});
}
}
//firestore URL upload
Future<void> onsend() async {
//uploading to cloudfirestore
FirebaseFirestore firebaseFirestore = FirebaseFirestore.instance;
await firebaseFirestore
.collection("users")
.doc("${loggedInUser.uid}")
.collection("reco")
.add({'downloadURL': _filePath}).whenComplete(() =>
showSnackBar("Image uploaded successful", Duration(seconds: 2)));
}

This is my code I use upload and get image url from Firebase storage:
Future<String> uploadImageToFirebase(File imageFile) async {
var user = StaticVariable.myUser!;
String imagePath = '';
try {
String downloadUrl;
FirebaseStorage firebaseStorage = FirebaseStorage.instance;
Reference ref = firebaseStorage.ref(
'uploads-images/${user.profileId}/images/${DateTime.now().microsecondsSinceEpoch}');
TaskSnapshot uploadedFile = await ref.putFile(imageFile);
if (uploadedFile.state == TaskState.success) {
downloadUrl = await ref.getDownloadURL();
imagePath = downloadUrl;
}
return imagePath;
} catch (e) {
return '';
}
}
I try to improve from above code:
Future<void> _onFileUploadButtonPressed() async {
FirebaseStorage firebaseStorage = FirebaseStorage.instance;
String downloadUrl = '';
setState(() {
_isUploading = true;
});
try {
Reference ref = firebaseStorage
.ref()
.child("${loggedInUser.uid}/records1")
.child(
_filePath.substring(_filePath.lastIndexOf('/'), _filePath.length));
TaskSnapshot uploadedFile = await ref.putFile(File(_filePath));
if (uploadedFile.state == TaskState.success) {
downloadUrl = await ref.getDownloadURL();
}
widget.onUploadComplete();
onsend();//send downloadURL after get it
} catch (error) {
print('Error occured while uplaoding to Firebase ${error.toString()}');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Error occured while uplaoding'),
),
);
} finally {
setState(() {
_isUploading = false;
});
}
}

Related

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

Cannot get the download link after uploading files to firebase storage Flutter

so this is the my file picking and file upload code
class Storage with ChangeNotifier {
PlatformFile? pickedFile;
UploadTask? uploadTask;
Future uploadFile() async {
final path = 'files/${pickedFile!.name}.png';
final file = File(pickedFile!.path!);
final ref = FirebaseStorage.instance.ref().child(path);
ref.putFile(file);
try {
final snapshot = await uploadTask!.whenComplete(() {});
final urlDownload = await snapshot.ref.getDownloadURL();
print(urlDownload);
} catch (e) {
print("this is the error $e " );
}
}
void pickFile() async {
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
File file = File(result.files.single.path!);
pickedFile = result.files.first;
} else {
print("no image picked");
}}}
the code works for upload the image but after that i didnt get any download link, the error is "Null check operator used on a null value" i dont know how to fix it, im still new in this topic, help please
i got the answer, need to change the uploadFile method to this
Future uploadFile() async {
final path = 'files/${pickedFile!.name}.png';
final file = File(pickedFile!.path!);
FirebaseStorage storage = FirebaseStorage.instance;
Reference ref = storage.ref().child(path);
UploadTask uploadTask = ref.putFile(file);
uploadTask.then((res) {
res.ref.getDownloadURL();
});
try {
final snapshot = await uploadTask.whenComplete(() {});
final urlDownload = await snapshot.ref.getDownloadURL();
print(urlDownload);
} catch (e) {
print("this is the error $e " );
}
}

uploading multiple xfiles to firebase storage

I am trying to upload multiple (max 5) xfiles images (image_picker library) to firebase storage. currently, it uploads only one with the below method:
Future<void> addProduct({
BuildContext? ctx,
String? proName,
String? productDescription,
double? count,
double? price,
required List<XFile> images
}) async {
try {
var imageUrls = await Future.wait(images.map((_image) =>
uploadFile(_image)));
await firestore
.collection(outletsCollection)
.doc(_currentUserOutletId)
.set({
products: FieldValue.arrayUnion([
{
productId: Uuid().v4(),
productName: proName,
prodDesc: productDescription,
countInStock: count,
productPrice: price,
productImg: FieldValue.arrayUnion([imageUrls]),
}
]),
});
} catch (err) {
String errMsg = "error blahblah";
errorDialog(ctx!, errMsg);
}
notifyListeners();
}
for the uploadFile method i tried using images.forEach() instead of .map(), but it gave me void type error. uploadFile method:
Future<String> uploadFile(XFile _image) async {
var storageReference = storage
.ref()
.child('product_images')
.child(_currentUserOutletId!)
.child(Uuid().v4());
final metadata = SettableMetadata(
contentType: 'image/jpeg',
customMetadata: {'picked-file-path': _image.path},
);
if (kIsWeb) {
await storageReference.putData(await _image.readAsBytes(), metadata);
} else {
await storageReference.putFile(io.File(_image.path), metadata);
}
return await storageReference.getDownloadURL();
}
so, at the end only one image is uploaded and addProduct() does not add product to firestore database. log in android studio returns nothing. I couldn't find a method that would work with the xfile. help appreciated very much!
List<XFile> _imageFileList;
try{
final pickedFile = await _picker.pickMultiImage();
setState(() {
_imageFileList = pickedFile;
_imageFileList.forEach((element) async {
firebase_storage.FirebaseStorage storage = firebase_storage.FirebaseStorage.instance;
var date = DateTime.now().millisecondsSinceEpoch;
try {
setState(() {
_loading = true;
});
firebase_storage.UploadTask task = firebase_storage.FirebaseStorage.instance.ref('uploads/photos/'+date.toString()+'_image.png').putData(await element.readAsBytes(), SettableMetadata(contentType: 'image/jpeg'));
await storage.ref('uploads/file-to-upload.png').putData(await element.readAsBytes(), SettableMetadata(contentType: 'image/jpeg'));
firebase_storage.TaskSnapshot downloadUrl = (await task);
String url = (await downloadUrl.ref.getDownloadURL());
// print(url.toString());
} on FirebaseException catch (e) {
// e.g, e.code == 'canceled'
setState(() {
_loading = false;
});
}
});
try this way using image_picker plugin. You can get url after image upload and you have yo it in your data.

How to track the uploading process on firebase with flutter?

I have this future function that will upload a video to firebase, I want to track this uploading process in percentage, so after the uploading process is completed, I will get the url.
Code
Future storageupload() async {
try {
if (controller = null) {
dialog('Error', 'Please Provide A Video Name', () => {});
} else {
StorageReference ref = FirebaseStorage.instance
.ref()
.child("Khatma 1")
.child("Videos")
.child(controller.text != null ? controller.text : "");
StorageUploadTask uploadTask = ref.putFile(
File(Variables.lastVideoPath),
StorageMetadata(contentType: 'video/mp4'));
}
} catch (e) {
print(e);
}
}
Future uploadToStorage() async {
try {
await storageupload();
final downloadUrl = await FirebaseStorage.instance
.ref()
.child("Khatma 1")
.child('Videos')
.child(controller.text)
.getDownloadURL();
final String url = downloadUrl.toString();
print(url);
} catch (error) {
print(error);
}
}
You can get by listening to TaskSnapshot Stream.
uploadTask.snapshotEvents.listen((TaskSnapshot snapshot) {
double _progress = snapshot.bytesTransferred.toDouble() / snapshot.totalBytes.toDouble();
});
For more info: https://pub.dev/documentation/firebase_storage/latest/firebase_storage/StorageTaskSnapshot-class.html
If you are using an older version of Firebase storage i.e snapshotEvents is not available.
This should work for you.
uploadTask.events.listen((event) {
double _progess = event.snapshot.bytesTransferred.toDouble() / event.snapshot.totalByteCount.toDouble();
});

How to upload image on cloud firestore linked to an entry?

I am trying to upload image on cloud firestore. But there is a error I am not able to catch.
I am using the code under uploadFile from here
Future<void> getImage() async {
var image = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
widget._image = image;
print("added image");
});
uploadImage();
}
Future uploadImage() async {
String fileName = DateTime.now().millisecondsSinceEpoch.toString();
StorageReference reference = FirebaseStorage.instance.ref().child(fileName);
StorageUploadTask uploadTask = reference.putFile(widget._image);
StorageTaskSnapshot storageTaskSnapshot = await uploadTask.onComplete;
storageTaskSnapshot.ref.getDownloadURL().then((downloadUrl) {
widget.photourl = downloadUrl;
}, onError: (err) {
print('Error');
});
}
'added image' prints on the terminal, so there isn't a problem in that it seems.
photourl is null, but it should contain the url.
Thank you.
In the above code, you are just getting an image URL from Firebase storage. You need to update the photoURL in Firestore also.
Future<void> updateOneField = database
.collection('entries')
.document('D3idV9o7uWT4pWvby643')
.updateData(
{
"photourl": downloadUrl
});
It seems the problem was because of state of widget. This solved it
Future uploadImage() async {
String fileName = DateTime.now().millisecondsSinceEpoch.toString();
StorageReference reference = FirebaseStorage.instance.ref().child(fileName);
StorageUploadTask uploadTask = reference.putFile(widget._image);
StorageTaskSnapshot storageTaskSnapshot = await uploadTask.onComplete;
storageTaskSnapshot.ref.getDownloadURL().then((downloadUrl) {
setState(() {
widget.photourl = downloadUrl;
});
}, onError: (err) {
print('Error');
});
}