Can't get a proper URL when Image from Storage Firebase is linked to CloudFirestore - flutter

I cant get a valid URL to retrieve in my method when images are linked to CloudFirestore from Storage in Firebase:
Future uploadImage(BuildContext context) async {
String fileName = basename(_imageFile.path);
Reference firebaseStorageRef =
FirebaseStorage.instance.ref().child('ifprofile/$fileName');
UploadTask uploadTask = firebaseStorageRef.putFile(_imageFile);
TaskSnapshot taskSnapshot = await uploadTask.whenComplete(() {
var firebaseUser = FirebaseAuth.instance.currentUser;
FirebaseFirestore.instance.collection('/userProfile').add({
"imageUrl": _imageFile.path,
});
FirebaseFirestore.instance
.collection('/influencerUser')
.doc(firebaseUser.uid)
.update({
// All fields you want to update in a document
'imageUrl': IfUserProfile.imageUrl,
});
// Finish to Link images to Cloud Firestore
});
taskSnapshot.ref
.getDownloadURL()
.then((value) => print("Image uploaded: $value"));
}
into cloud firestore I get URL like this:
/data/user/0/it.test.testapp/cache/image_picker5217031945896769637.jpg
any input please?

try to modify ur code a but like this
final url = await taskSnapshot.ref
.getDownloadURL();
then take that url and put it in your firestore db
here is some code
final storageRef = FirebaseStorage.instance.ref('$folderName/$imagename');
final uploadTaskSnapshot = await storageRef.put(image).future;
final imageUri = await uploadTaskSnapshot.ref.getDownloadURL();

Related

Firebase Storage URL is FutureString

in my flutter app, the user picture is loaded by Cached Network image command, which gets its url by stream builder from firestore.
I am trying to add the functionality to the user of changing his pic by pressing on the pic as following:
Selecting his pic with image picker.
upload it to firebase storage.
updating firestore usercollection document with new image url.
I created the below code.
The problem is getDownloadURL() is not returning actual string, but "Instance of 'Future'".
so the new link stored in firestore is not correct to be used by Cached Network Image.
how can I get the actual URl String?
My Future Function Code:
Future ChangeProfilePic() async {
String newimageurl = "";
FirebaseStorage storage = FirebaseStorage.instance;
Reference ref =
storage.ref().child("ProfileImages/$globaluserid".toString());
CollectionReference userscollectionref =
FirebaseFirestore.instance.collection('UsersCollection');
final ImagePicker _picker = ImagePicker();
final XFile? image = await _picker.pickImage(source: ImageSource.gallery);
File imagefile = File(image!.path);
UploadTask uploadTask = ref.putFile(imagefile);
uploadTask.whenComplete(() {
newimageurl = ref.getDownloadURL().toString();
print("Image Uploaded");
userscollectionref
.doc(globaluserid)
.update({'User_image_link': newimageurl});
print("Link is Updated");
}).catchError((onError) {
print("Error");
print(onError);
});
}
Like many calls in your code `` is an asynchronous call, whose result won't be available immediately, so it returns a Future that will at some point contain the value. You can use await to wait for such a Future to complete and get its value, similar to what you already do in await _picker.pickImage.
await ref.getDownloadURL().toString();
Another change to consider is that putFile returns a Task, but that is actually also a Future, which means that you can await that too.
Combining these two fact, you can simplify your code to:
final XFile? image = await _picker.pickImage(source: ImageSource.gallery);
File imagefile = File(image!.path);
await ref.putFile(imagefile);
newimageurl = (await ref.getDownloadURL()).toString();
print("Image Uploaded");
userscollectionref
.doc(globaluserid)
.update({'User_image_link': newimageurl});
print("Link is Updated");

Unhandled Exception: PlatformException(download_error, Object does not exist at location., null, null), but my Object does exists at the location

I m trying to upload the image on firebase, using this code:
Future<String> uploadCourseImage(filePath, courseName) async{
File file = File(filePath);
var timestamp = Timestamp.now().millisecondsSinceEpoch;
FirebaseStorage _storage = FirebaseStorage.instance;
try{
await _storage.ref().child('courseImage/${this.TeacherName}/$courseName$timestamp').putFile(file);
}on Exception catch(e){
print(e.hashCode);
}
String downloadURL = await _storage.ref().child('courseImage/${this.TeacherName}/$courseName$timestamp').getDownloadURL();
this.courseURL =downloadURL;
notifyListeners();
return downloadURL;
}
But I get this error:
Unhandled Exception: PlatformException(download_error, Object does not exist at location., null, null), but my Object does exists at the location
Using UploadTask class object helps in uploading the file I think.
Try this method for uploading image to Firebase Storage and extracting url after uploading is done.
Future uploadImage(BuildContext context) async {
FirebaseStorage storage = FirebaseStorage.instance;
String? email = FirebaseAuth.instance.currentUser!.email!;
Reference ref =
storage.ref().child('users/${email + DateTime.now().toString()}/Profile Image: ${DateTime.now().toString()}');
UploadTask uploadTask = ref.putFile(_image!);
final TaskSnapshot downloadUrl = (await uploadTask);
imageUrl = await downloadUrl.ref.getDownloadURL();
}
The below code worked fro me:
//Create a reference to the location you want to upload to in firebase
StorageReference reference =
storage.ref().child('courseImage/${this.TeacherName}/$courseName$timestamp');
//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();

How do i get the image download URL in database in Flutter

I want to get the image download link and store it in Firestore database. Bellow is the function to upload the image to Firebase storage, if the function is wrong can you please explain why and write me a function?
File _image1;
Future uploadPic() async {
StorageReference reference = storage.ref().child('image');
StorageUploadTask uploadTask = reference.putFile(_image1);
StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
String url = await taskSnapshot.ref.getDownloadURL();
imageUrl1 = url;
}
add return to the function to retrieve the output(url)
File _image1;
Future uploadPic() async {
StorageReference reference = storage.ref().child('image');
StorageUploadTask uploadTask = reference.putFile(_image1);
StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
String url = await taskSnapshot.ref.getDownloadURL();
imageUrl1 = url;
return url;
}
From this you can call the then function,
uploadPic().then((value)
{
DocumentReference docRef =
Firestore.instance.collection('collectionname').document(documentid);
docRef.setData({'pic' : value},merge:true)
});

How to upload a image url downloaded from firebase storage to firestore document for newly registered user?

I have made it till uploading the image to firebase storage and download the url.Here, I need to store the newly registered user information in an Firestore document. I am storing some details one of those is the image URL downloaded from firebase storage.
Now, I need to assign the downloaded Url to Firestore to access it in my dart pages.
uploadImage() async {
var random = Random(25);
final StorageReference fireref = FirebaseStorage.instance
.ref()
.child('profilepics/${random.nextInt(5000).toString()}.jpg');
StorageUploadTask task = fireref.putFile(profilepic);
StorageTaskSnapshot snapshottask = await task.onComplete;
String downloadUrl = await snapshottask.ref.getDownloadURL();
if (downloadUrl != null) {
userManagement.addProfilePic(downloadUrl.toString()).then((val) {
Navigator.of(context).pushReplacementNamed('/twelf');
});
}
}
The above is the code of getting the image url from firebase storage.And, If you can see I have called a method addProfilePic to add the downloaded URL to firestore. And the method is,
Future addProfilePic(picUrl) async {
//---
}
What Should i write in this method to upload url to firestore. I am not able to understand.
Additional code for understanding:
class UserManagement {
storeNewUser(user, context) {
Firestore.instance.collection('/userdetails').add({
'Email': user.email,
'uid': user.uid,
'displayName': user.fullname,
'photoUrl': user.photoUrl
}).then((value) {
Navigator.of(context).pop();
Navigator.of(context).pushReplacementNamed('/selectpic');
}).catchError((e) {
print(e);
});
}
And the below code is near registration the final code that upload data to firestore:
final String userId = await widget.auth
.createUserWithEmailAndPassword(_email, _password)
.then((signedInUser) async {
var userUpdateInfo = new UserUpdateInfo();
userUpdateInfo.displayName = _fullname;
userUpdateInfo.photoUrl = _imageurl;
//'https://cdn.mos.cms.futurecdn.net/QjuZKXnkLQgsYsL98uhL9X-1024-80.jpg';
final user = await FirebaseAuth.instance.currentUser();
user.updateProfile(userUpdateInfo).then((user) {
FirebaseAuth.instance
.currentUser()
.then(
(user) => {UserManagement().storeNewUser(user, context)})
.catchError((e) {
print(e);
});
}).catchError((e) {
print(e);
});
}).catchError((e) {
print(e);
});
print('Registered user: $userId');
}
Try this:
Future<String> uploadImage(profilepic) async {
StorageUploadTask uploadTask = storageRef.child("profilepics/${random.nextInt(5000).toString()}.jpg").putFile(profilepic);
StorageTaskSnapshot storageTaskSnapshot = await uploadTask.onComplete;
String downlaodUrl = await storageTaskSnapshot.ref.getDownloadURL();
return downlaodUrl;
}
// String imageUrl = await uploadImage(profilepic); You can store the value of imageUrl in firebase document.
Firestore.instance.collection('/userdetails').add({
// All fields you want to have in a document
'photoUrl': imageUrl; // use the image url variable
});
/// To update a currentUser document
Firestore.instance.collection('/userdetails')
.document(your_user_document_name_here)
.updateData({
// All fields you want to update in a document
'photoUrl': imageUrl; // use the image url variable
});

getDownloadURL returns null when uploadTask is complete but uploads image to storage

The image I am trying to upload to storage is successful, however when I want to use that image that was uploaded to store the URL into the database, it returns null for some reason.
Future<String> _uploadPic(String docRef, File file) {
FirebaseStorage _storage = FirebaseStorage.instance;
auth.currentUser().then((userID) async{
StorageReference reference = _storage.ref().child(userID).child(docRef);
StorageUploadTask uploadTask = reference.putFile(file);
String downloadURL = (await uploadTask.onComplete).ref.getDownloadURL().toString();
return downloadURL;
});
}
Log:
I/flutter (17507): debug: the uri is: null
Future<dynamic> _uploadPic(String docRef, File file) {
FirebaseStorage _storage = FirebaseStorage.instance;
// you need to return the result...
return auth.currentUser().then((userID) async {
StorageReference reference = _storage.ref().child(userID).child(docRef);
StorageUploadTask uploadTask = reference.putFile(file);
return (await uploadTask.onComplete).ref.getDownloadURL();
});
}
The getDownloadURL() method returns a Future. So if you call toString() on that, you get the string representation of the future, and not a download URL. Instead you'll want to wait for the getDownloadURL() future to also complete, and that will give you the URL.
String downloadURL = (await (await uploadTask.onComplete).ref.getDownloadURL()).toString();