'file.existsSync()': is not true - flutter

I am going to store an image in firebase storage. When I send file through image picker then its working fine. But when I manually pass link of image then it is showing an error that says:
'package:firebase_storage/src/storage_reference.dart':
Failed assertion: line 62 pos 12: 'file.existsSync()': is not true.
I am writing following code:
File image = File("assets/img/pic.jpg");
final StorageReference firebaseStorageRef =
FirebaseStorage.instance.ref().child('image');
InkWell(
child: Text("Tap to Upload"),
onTap: () {
firebaseStorageRef.putFile(image);
},
),

The error says it, the file doesn't exists, before doing that you should check if the file is there or create it if it's not
InkWell(
child: Text("Tap to Upload"),
onTap: () async {
File image = await File("assets/img/pic.jpg").create();
// it creates the file,
// if it already existed then just return it
// or run this if the file is created before the onTap
// if(image.existsSync()) image = await image.create();
firebaseStorageRef.putFile(image);
},
),
Also I'm not sure if you can change/create files in the assets folder, if that doesn't work maybe try to put the file in a temp directory of your app

Related

Image not updated after changing it's File Path in Flutter

By facing image quality not decreased after compressing it multiples time I thought that plugin is not working. But after dumping file on File Storage during debugging, It was Actually Compressed and Image Quality was decreased by 25 %.
But Image is not Updating after setting it's State. I've read many articles and things. I've used all the things I've Found. I tried to clear Flutter's Image Cache and Painting Binding and Stuff. I also tried to empty temporary directory.
imageCache.clearLiveImages();
PaintingBinding.instance.imageCache.clear();
var appDir = (await getTemporaryDirectory()).path;
Directory(appDir).delete(recursive: true);
Here's My Code. First _imagePath is the image it receives and it's displayed properly. When we compress and update the File Path, Image's State is not changed (Image is not changed).
CircleAvatar(
radius: 150,
backgroundImage: FileImage(File(_imagePath)),
),
TextButton(
child: Text(
'Compress',
style: TextStyle(fontSize: 22),
),
onPressed: () {
setState(() async {
// Compressing File
File compressedFile =
await FlutterNativeImage.compressImage(
_imagePath,
quality: 25,
);
_imagePath = compressedFile.path;
});
},
),
I used Value Notifier of flutter which notifies if value changes for image.

File is not loading from DocumentDirectory Path Flutter

i am new to Flutter.
I build simple demo app in which user can fill simple form and once user press button then those data will save into SQLite DB.
There's only 3 content. Title, Image Path (Image saved to DocumentDirectory), Location Details.
Add Screen
Listing Screen
Below is my code to copy image to path.
Future<void> _takePicture() async {
final picker = ImagePicker();
final pickedFile = await picker.getImage(
source: ImageSource.camera,
maxWidth: 600,
);
if (pickedFile == null) {
return;
}
setState(() {
_storedImage = File(pickedFile.path);
});
final appDir = await syspaths.getApplicationDocumentsDirectory();
String relativePath = '/' +
DateTime.now().millisecondsSinceEpoch.toString() +
path.basename(pickedFile.path);
String newPath = '${appDir.path}' + relativePath;
final savedImage = await File(pickedFile.path).copy('$newPath');
widget.onSelectImage(savedImage);
}
Listing Item Code
child: Card(
elevation: 5,
child: ListTile(
leading: CircleAvatar(
backgroundImage: FileImage(greatPlaces.items[index].image),
),
title: Text(greatPlaces.items[index].title),
subtitle: Text(
greatPlaces.items[index].location.address),
onTap: () {
print(greatPlaces.items[index].image);
//Go to detail page...
},
),
)
ISSUE ==> When i add new place and view the added place list then images are loading fine but when i stop and rerun project then i am getting below error and image is not loading.
ERROR
════════ Exception caught by image resource service
════════════════════════════ The following FileSystemException was
thrown resolving an image codec: Cannot open file, path =
'/var/mobile/Containers/Data/Application/607FB621-ABDA-472F-8B7A-D9B1BEC4A15D/Documents/1616508266743image_picker_34814E6F-218C-48F6-BE36-C4D7949F0496-1511-0000017478AD7F14.jpg'
(OS Error: No such file or directory, errno = 2) When the exception
was thrown, this was the stack
#0 _File.open. (dart:io/file_impl.dart:356:9) (elided 13 frames from dart:async) Path:
/var/mobile/Containers/Data/Application/607FB621-ABDA-472F-8B7A-D9B1BEC4A15D/Documents/1616508266743image_picker_34814E6F-218C-48F6-BE36-C4D7949F0496-1511-0000017478AD7F14.jpg ════════════════════════════════════════════════════════════════════════════════
I downloaded app container and confirm image exist at the same place. greatPlaces.items[index].image return the File
NOTE: ==> Same code working fine in Android Devices.
it will be very helpful if someone help me with this. Thanks
Path of the documents directory changes on iOS after each app update. Therefore, one can not store absolute paths to the files stored in this directory. Instead, it is required to store the relative paths and then join them with the value returned by getApplicationDocumentsDirectory() every time to access the files.

type 'Future<File>' is not a subtype of type 'File'

Important: I have searched a lot but did not find any solution that I can understand.
I am using photo manager to show images and then after selecting an image I want to navigate to the next screen and show that image there (later I want to upload that image to firebase storage).
So the type of File I am getting from the photo_manager package is Future < File > and I am receiving File from the second screen.
How can I convert future to file?
First Screen:
IconButton(
icon: const Icon(Icons.arrow_forward, color: primaryColor),
onPressed: () {
Get.to(PostDetail(
imgFile:
_controller.mediaList[_controller.selectedImageIndex].file,
));
},
),
Second Screen:
On the second screen, I'm getting File.
final File imgFile;
const PostDetail({this.imgFile});
Source Code:: Add Post Page
So as described in photo_manager docs, you need to get the file from the AssetEntity list before moving to the next page.
So on button pressed to go to next page get the file and then pass it to the Page
Below code should work:
IconButton(
icon: const Icon(Icons.arrow_forward, color: primaryColor),
onPressed: () async {
File file = await _controller.mediaList[_controller.selectedImageIndex].file; // image file
Get.to(PostDetail(
imgFile: file,
));
},
),
File and Future<File> are 2 different things. the File is a variable that its value is in the present. but Future<File> as its name suggests, its value exist in the Future which means its value takes some time to reach you.
for example, if you send a request to a webserver, the response takes some time to reach you. so, in that case the response is a Future.
in your case the image you are trying to get is supplied in a way that it takes time. to get the File from Future<File> you have to wait. So before sending the file to this Screen, use an async and wait to turn the Future<File> to File. (i dont know how you get the file)
for example,
File myFile = await getFileorWhaterver();
Your _controller.mediaList[_controller.selectedImageIndex].file is a Future<File> means that the value of the File is promised to be returned sometimes in the future. This usually because you are doing a network call asynchronously to get the data from API.
In order to convert it to File, you need to await till the moment that value is available. However you cannot do an async/await within the UI, that's why Flutter provide a widget named FutureBuilder to wait for a certain Future value, then let you use that value in the UI.
In your case, you can do this:
FutureBuilder(
future: _controller.mediaList[_controller.selectedImageIndex].file,
builder: (context, snapshot) {
return IconButton(
icon: const Icon(Icons.arrow_forward, color: primaryColor),
onPressed: () {
if (snapshot.hasData)
Get.to(PostDetail(imgFile: snapshot.data));
},
);
})

How to send user out of the application - To a specific directory path

I have a specific path where user files are exported under the following path:
e.g : /storage/emulated/0/Android/data/com.example.app_name/files
However the problem is not how generate the path but how to do this redirection (open the folder where the file is stored).
I've tried to use the plugin url_launcher but apparently it doesn't work.I tried to launch this path as url:
code example :
FlatButton(
onPressed: () async{
// _localPath returns /storage/emulated/0/Android/data/com.example.app_name/files
final path = await _localPath;
if (await canLaunch(path)) {
await launch(path);
} else {
throw 'Could not launch $path';
}
},
child: Text('Navigate to App storage Folder'),
),
The user exported the data as csv file and he want to use that file.
The expected result : user will be redirected to the path (folder files) and exit the Flutter application.
PS : I'm targeting only Android Platform.
I seem to have found a solution for your question with a package called open_file.
You can simply point to the path you want to open and it will ask the OS for the app you want to use to handle files or use what is set as your default.
Basic code example:
class OpenDirectoryPath extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Center(
child: RaisedButton(
child: Text('Open path'),
onPressed: () {
_openPath('/storage/emulated/0/Download/');
},
),
);
}
void _openPath(String path) async {
OpenFile.open(path);
}
}
(tested in Android)

Flutter remove image after upload using image_picker package

I have managed to upload an image using the image picker package as shown below:
final picker = ImagePicker();
Future selectPhoto() async {
final pickedFile = await picker.getImage(source: ImageSource.gallery);
setState(() {
_image = File(pickedFile.path);
});
}
The image has been displayed on the device where I have a remove button which I can use to remove the image and upload another before saving it.
child: Container(
height: height * 0.2,
width: width * 0.2,
child: Image.file(
_image,
fit: BoxFit.fill,
),
),
My question is how can I remove the image from cache as this piece is not working
onTap: () {
setState(() {
imageCache.clear();
print('removes $_image');
});
},
You have a misunderstanding of what the cache is compared to explicitly storing a file in memory with your code. Flutter may store images that you use in widgets in a cache so that they may load faster in the future. imageCache.clear(); does clear the cache and is likely doing it's work in your code. However, your method of checking if the image is still cached is flawed.
imageCache.clear(); only clears the cache, it does not delete the file that you're passing to the Image.file widget. This means that _image(the file variable you have stored in memory) will persist even over the cache clearing. To truly delete this image you could use the delete method or if you just want to stop showing the image, deference the file by setting the file reference to null:
_image = null;
Solved it by calling a method within the button which had set state method where the path was returned back to null
clearimage() {
setState(() {
_image = null;
});
}