I have tried to add a function that allow the user to add a profile picture inside my app.
late String? profileURL = '';
late File userProfilePicture;
...
Future pickAndUploadImage() async {
final ImagePicker _picker = ImagePicker();
try {
XFile? image = (await _picker.pickImage(source: ImageSource.gallery));
print('eee');
await new Future.delayed(const Duration(seconds: 2));
userProfilePicture = File(image!.path);
print(userProfilePicture);
print(File(image.path));
if (userProfilePicture != File(image.path)) {
print('It didnt work sorry');
Navigator.pop(context);
}
else {
print('Should be startting to put file in');
var snapshot = await storage
.ref()
.child('userProfiles/$userEmail profile')
.putFile(userProfilePicture);
print('file put in!');
profileURL = await snapshot.ref.getDownloadURL();
}
setState(() {
DatabaseServices(uid: loggedInUser.uid).updateUserPhoto(profileURL!);
print(profileURL);
});
} catch (e) {
print(e);
}
}
The thing is, this line : if (userProfilePicture != File(image.path)) seen not to work. I do not know why, but here is my output :
> flutter: eee
>flutter: 2 File: '/Users/kongbunthong/Library/Developer/CoreSimulator/Devices/..../tmp/image_picker_3912CA1D-AC60-4C84-823F-EB19B630FD1C-11650-0000061E644AD3FA.jpg'
> flutter: It didnt work sorry
The second line shows that there is 2 file overlapping each other, and doesn't that means the 2 files are the same?
And if it is the same, it should print out Should be starting to put the file in. But instead, it prints out: It didn't work sorry.
Any help is VERY MUCH appreciated!
The two files are different File objects and so the equality check will fail.
You can check if the two File paths are the same like this:
if (userProfilePicture.path != image.path)
Related
How to passing the list of image to next page i try to declare at the top of code and do like this but it said
PostView({File? keepImage}) : this.keepImage = keepImage ?? [];
'keepImage' isn't a field in the enclosing class.
Try correcting the name to match an existing field, or defining a field named
i have keep image into
final List<File> keepImage = [];
and here is pick image function
Future<void> chooseImage() async {
final pickedFile = await picker.getImage(source: ImageSource.gallery);
setState(() {
keepImage.add(File(pickedFile!.path));
});
if (pickedFile?.path == null) retrieveLostData();
}
Future<void> retrieveLostData() async {
final LostData response = await picker.getLostData();
if (response.isEmpty) {
return;
}
if (response.file != null) {
setState(() {
keepImage.add(File(response.file!.path));
});
} else {
print(response.file);
}
}
There are several ways you can do this.
The easiest is using shared preferences to store the image url in cache and so you can retrieve it wherever you want. Another is using arguments, when navigating to the other page, pass the id of this image for it.
how I can add multiple images and store them in an array in firebase ?
every container has a + button so the user can add single image per container then I WANT TO STORE them in my firebase
any help would be greatly appreciated ^^
what you are showing in your image is fbCloudStore which is use to store information in json structure.
To store the images you may use fbStorge.
here's an snippet I use on my project:
Future<String?> uploadFile({
required FilePickerResult file,
required String fileName,
required FirebaseReferenceType referenceType,
}) async {
try {
final ref = _getReference(referenceType);
final extension = path.extension(file.files.first.name);
final _ref = ref.child(fileName + extension);
late UploadTask uploadTask;
if (kIsWeb) {
uploadTask = _ref.putData(file.files.first.bytes!);
} else {
uploadTask = _ref.putFile(File(file.files.single.path!));
}
var url;
await uploadTask.whenComplete(
() async => url = await uploadTask.snapshot.ref.getDownloadURL());
print(url);
return url;
} on FirebaseException catch (_) {
print(_);
}
}
Note that I'm returning the URL of fbStorage in order to associate it with fbCloudStorage
final url =
await FirebaseStorageSer.to.uploadFile(
file: result,
fileName: STORAGE_USER_PROFILE_PICTURE,
referenceType: FirebaseReferenceType.user,
);
if (url != null) {
await FirebaseAuthSer.to
.updateUserProfile(photoUrl: url);
}
FirebaseReferenceType.user is just a simple enum to simplify ref targets.
I want to upload a picture choosen from gallery to Firestore Storage, this is my first time but I read docs and took a look on the internet, this is what I wrote (it works without errors but doing nothing on the storage).
Code below, I tested imgFromGallery and it works maybe the problem are Storage functions.
Future<File> imgFromGallery() async {
try {
final ImagePicker _picker = ImagePicker();
final PickedFile imageFile =
await _picker.getImage(source: ImageSource.gallery, imageQuality: 50);
//If there is no image selected, return.
if (imageFile == null) return null;
//File created.
File tmpFile = File(imageFile.path);
//it gives path to a directory - path_provider package.
final appDir = await getApplicationDocumentsDirectory();
//filename - returns last part after the separator - path package.
final fileName = tmpFile.path.split('/').last;
//copy the file to the specified directory and return File instance.
return tmpFile = await tmpFile.copy('${appDir.path}/$fileName');
} catch (e) {
print(e);
return null;
}
}
//Save file to Storage function
Future<void> setPicture(String pathStorage) async {
try {
final File file = await imgFromGallery();
if (file == null) return;
FirebaseStorage.instance.ref(pathStorage).putFile(file);
return;
} catch (e) {
print(e);
}
}
P.S. : I would like to return the URL of the uploaded picture as return of "setPicture" but I still don't know how to do this.
You are just few steps away!
TaskSnapshot task = await FirebaseStorage.instance.ref(pathStorage).putFile(file);
After successful upload, you will get TaskSnapshot. That has a reference member ref.
String image_url = await task.ref.getDownloadURL();
This image_url is the URL of the uploaded picture.
ref: What is the the method to use onComplete function to add Images to Firebase Storage
I'm using Firebase storage with flutter. If the upload operation fails for whatever reason (e.g. exceeds size limits set in console), it causes a StorageException.
I want to do something like this:
try {
final uploadTask = ref.putFile(docFile);
taskSnapshot = await uploadTask.onComplete;
} on StorageException catch (err) {
// Do something
}
But there isn't any StorageException type and I can't find a way to catch any and all exceptions. Any ideas?
You can do something like the following instead.
import 'package:firebase_core/firebase_core.dart' as firebase_core;
try {
final uploadTask = ref.putFile(docFile);
taskSnapshot = await uploadTask.onComplete;
} on firebase_core.FirebaseException catch(e) {
if (e.code == 'permission-denied') {
/// Real permisssion-denied handling
print('User does not have permission to upload to this reference.');
}
if (e.code == 'the-error-code-printed-to-console') {
///the-error-code-printed-to-console handling
print('printing what you want');
}
}
This handles errors and checks if it's due to permission. If you are looking for another cause, you can just print the e.code to the console first, copy the code and check if the code copied previously from console is equal to e.code.
try catch doesnt work very well, I solved it like this:
}, onError: (e) {
debugPrint('Exception::: ==========>>>>>>> ${e.toString()}');
});
It get it that way
I am having trouble in creating a progress bar to indicate the process of me uploading an image to firebase storage.
Future getImage(BuildContext context) async {
final picker = ImagePicker();
final pickedFile = await picker.getImage(source: ImageSource.gallery);
setState(() {
_image = File(pickedFile.path);
});
StorageReference firebaseStorageRef = FirebaseStorage.instance.ref().child('profile/${Path.basename(_image.path)}}');
StorageUploadTask uploadTask = firebaseStorageRef.putFile(_image);
var dowurl = await (await uploadTask.onComplete).ref.getDownloadURL();
setState(() {
_imageURL = dowurl.toString();
});
print(_imageURL);
}
This is the code that I have written to upload the image and getting the image URL.
Hope someone can help me up thanks!
you can listen to the events on your uploadTask.
Here:
uploadTask.events.listen((event) {
setState(() {
_progress = event.snapshot.bytesTransferred.toDouble() /
event.snapshot.totalByteCount.toDouble();
});
}).onError((error) {
// do something to handle error
});
Now you can just display the progress like this:
Text('Uploading ${(_progress * 100).toStringAsFixed(2)} %')
To create a progress bar:
LinearProgressIndicator(
value: _progress,
)
Hope that helps.
The answer by Ayush Shekhar is correct, but outdated on some parts due to the rapid updating on firebase plugins.
On top of state class
double? _progress;
...
In the upload method, you can setup like this.
uploadTask.snapshotEvents.listen((event) {
setState(() {
_progress =
event.bytesTransferred.toDouble() / event.totalBytes.toDouble();
print(_progress.toString());
});
if (event.state == TaskState.success) {
_progress = null;
Fluttertoast.showToast(msg: 'File added to the library');
}
}).onError((error) {
// do something to handle error
});
You can get the download link like this.
uploadTask.then((snap) async {
final downloadURL = await snap.ref.getDownloadURL();
print(downloadURL);
});
...
Use the _progress in UI like this.
if (_progress != null)
LinearProgressIndicator(
value: _progress,
minHeight: 2.0,
color: Constants.primaryColor,
),
Use Future Builder and pass this getImage inside future builder Future Builder Example
or You can use Modal Progress HUD
Check this, it will work for both video and images:
final fil = await ImagePicker().pickVideo(source: ImageSource.gallery);
final file = File(fil!.path);
final metadata = SettableMetadata(contentType:"video/mp4");
final storageRef = FirebaseStorage.instance.ref();
final uploadTask = storageRef
.child("images/path/to/video")
.putFile(file, metadata);
// Listen for state changes, errors, and completion of the upload.
uploadTask.snapshotEvents.listen((TaskSnapshot taskSnapshot) {
switch (taskSnapshot.state) {
case TaskState.running:
final progress =
100.0 * (taskSnapshot.bytesTransferred / taskSnapshot.totalBytes);
print("Upload is $progress% complete.");
break;
case TaskState.paused:
print("Upload is paused.");
break;
case TaskState.canceled:
print("Upload was canceled");
break;
case TaskState.error:
// Handle unsuccessful uploads
break;
case TaskState.success:
print("Upload is completed");
// Handle successful uploads on complete
// ...
break;
}
});