Saving image permenantly after user upload it in flutter - 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();
}

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

Image is null after its picked by using image_picker package and saved on local memory (flutter)

Description:
I'm using (image_picker: ^0.8.5+3) package to pick the images from gallery and camera and then upload them on backend server (django by using django rest framework)
Issue:
Image is getting null outside picker function, even though state has been set by using setSatet(() {}) method
Failed Solutions:
I tried to save the image locally before uploading the image on the backend, But image still shown null once its used or referenced outside picker function
Note: backend API's works fine and i can upload images by using postman
picker function:
// Get image from gallery and store it locally
Future<File?> _getFromGallery() async {
PickedFile? image = await ImagePicker.platform.pickImage(source: ImageSource.gallery);
if (image == null) {
return null;
}
final File file = File(image.path);
final Directory directory = await getApplicationDocumentsDirectory();
final imagepath = directory.path;
final String fileName = path.basename(image.path);
File newImage = await file.copy('$imagepath/$fileName');
setState(() {
_imagelocal = newImage;
print('image.path1');
print(_imagelocal!.path);
});
}
Uploading image function:
_uploadimage() async {
Map<String,String> header = {
"Content-Type":"application/octet-stream)"
};
print("uploaded image invoked");
var request = http.MultipartRequest('POST', Uri.parse('http://192.168.1.15:8000/api/uploadimage'));
// request.files.add(await http.MultipartFile('image',http.ByteStream(image.openRead()).cast(),await image.length(),filename:image.name, contentType: MediaType('image', 'jpg')));
request.files.add(await http.MultipartFile('LoadModelImage',http.ByteStream(_imagelocal!.openRead()).cast(),await _imagelocal!.length(),));
request.headers.addAll(header);
//for completeing the request
var response =await request.send();
//for getting and decoding the response into json format
var responsed = await http.Response.fromStream(response);
final responseData = json.decode(responsed.body);
if (response.statusCode==201) {
print("SUCCESS");
print(responseData);
}
else {
print("ERROR");
}
}

How to get Download URL from Firebase Storage in 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;
}

iOS app crashes when calling this function 2 times in a row (Firebase Storage, Flutter)

My app crashes when calling "_submit" function 2 times in a row.
I can pick the picture from gallery and upload it to Firebase Storage but if I call it again the the whole app crashes.
From this button :
floatingActionButton: FloatingActionButton(
onPressed: () => _submit(),
Submit calls a Provider of type Database :
Future<void> _submit() async {
widget.database = Provider.of<Database>(context, listen: false);
await widget.database
.setPicture("regione/citta/comune/lavoro/IDArtista/profilo.png");
return;
}
That calls a function that uploads a picture taken from "imgGallery()" to the database :
Future<void> setPicture(String pathStorage) async {
try {
final File file = await imgFromGallery();
if (file == null) return;
TaskSnapshot task =
await FirebaseStorage.instance.ref(pathStorage).putFile(file);
String image_url = await task.ref.getDownloadURL();
return;
} catch (e) {
print(e);
return;
}
}
imgGallery :
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;
}
}
EDIT : Solved using a real device instead of emulators.
Which device are you experiencing this in? I'm also having this error but only on iOS emulator. It has to do with the Image_Picker package and the FocusNode. Look at this issue on github

Flutter form builder package image picker firestore flutter

i am using FormBuilderImagePicker from package Flutter form builder
I want to use the img path but i am not able to do so
sending() async {
var storageimage =
FirebaseStorage.instance.ref().child('/google/google');
var task = storageimage.putFile();
imgurl = await (await task.onComplete).ref.getDownloadURL();
// await Firestore.instance.collection('twst').add(
// {
// 'img': imgurl.toString(),
// },
// );
}
i want to use that function with the imagepicker
but the problem is i am not able to find path to use putfile
To get the path of the FormBuilderImagePicker, the toString() method of the class prints the path.
Here is an example of how you can print in a container the Text field including FormBuilderImagePicker which have the path.
Then you will need to pass the image or file to the putFile method.
You can also use the ImagePicker pickImage class method to get the file.
sending() async {
File image;
try {
//Get the file from the image picker and store it
image = await ImagePicker.pickImage(source: ImageSource.gallery);
// Throws error when you don't select any image or when you don't have permissions
} on PlatformException catch (e) {
return;
}
//Create a reference to the location you want to upload to in firebase
StorageReference reference = FirebaseStorage.instance.ref().child("/google/google");
//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();
}