Like this I have a code:
final Storage storage = Storage();
// ....
onPressed: () async {
final results = await FilePicker.platform.pickFiles(
type: FileType.image,
allowMultiple: false,
allowedExtensions: ['jpg', 'png', "jpeg"],
);
if (results == null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Resim seƧmediniz."),
backgroundColor: Color.fromARGB(255, 36, 36, 36),
),
);
return null;
}
final path = results.files.single.path!;
final fileName = results.files.single.name;
Storage.uploadFile(path, fileName);
},
Also I have storage_services.dart:
import 'dart:io';
import 'package:firebase_storage/firebase_storage.dart';
class Storage {
final FirebaseStorage _storage = FirebaseStorage.instance;
Future<void> uploadFile(String filePath, String fileName) async {
File file = File(filePath);
try {
await _storage.ref("$fileName").putFile(file);
} on Exception catch (e) {
print(e);
}
}
}
My codes were like this. I am getting an error. Error:
Instance member 'uploadFile' can't be accessed using static access.dartstatic_access_to_instance_member
I'm trying to code by looking at this video: https://www.youtube.com/watch?v=sM-WMcX66FI
How can I solve the problem? Thanks in advance for your help.
Related
I need to pick an image from gallery and also have an another field for drag image.
For drag and drop field I used flutter_dropzone.
and used getFileStream(event) data to upload data into server.But file_picker: ^5.2.4 is used to pick image from gallery.So how to get filestream data from this package.
I got bytes but that is not working I needed filestream value
Code using file_picker
void chooseImage() async {
pickedFile = await FilePicker.platform.pickFiles(
type: FileType.custom,
withReadStream: true,
allowedExtensions: [
'jpg','jpeg','png'
]
);
if (pickedFile != null) {
try {
base64 = pickedFile!.files.first.bytes;
base64String.value=base64.toString();
String mime = pickedFile!.files.first.extension.toString();
getS3url("image/$mime" ,base64String.value,from: "cameraIcon");
//withReadStream
//getFileStream(event);
} catch (err) {
print(err);
}
} else {
}
}
Copied from https://github.com/miguelpruivo/flutter_file_picker/wiki/FAQ
import 'package:file_picker/file_picker.dart';
import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';
import 'package:mime/mime.dart';
void main() async {
final result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: [
'jpg',
'png',
'mp4',
'webm',
],
withData: false,
withReadStream: true,
);
if (result == null || result.files.isEmpty) {
throw Exception('No files picked or file picker was canceled');
}
final file = result.files.first;
final filePath = file.path;
final mimeType = filePath != null ? lookupMimeType(filePath) : null;
final contentType = mimeType != null ? MediaType.parse(mimeType) : null;
final fileReadStream = file.readStream;
if (fileReadStream == null) {
throw Exception('Cannot read file from null stream');
}
final stream = http.ByteStream(fileReadStream);
final uri = Uri.https('siasky.net', '/skynet/skyfile');
final request = http.MultipartRequest('POST', uri);
final multipartFile = http.MultipartFile(
'file',
stream,
file.size,
filename: file.name,
contentType: contentType,
);
request.files.add(multipartFile);
final httpClient = http.Client();
final response = await httpClient.send(request);
if (response.statusCode != 200) {
throw Exception('HTTP ${response.statusCode}');
}
final body = await response.stream.transform(utf8.decoder).join();
print(body);
}
The following is the code i was trying to implement in. The future method pickImage i guess it is the one having the problem. I am extending the class with GetxController. The method is expected to pick and crop the selected image using the image cropper, and then set the cropped image to the imageFile variable if the cropping was successful.
import 'dart:io';
import 'package:pamoja/app/data/const.dart';
import 'package:pamoja/app/data/firebase/firebase_functions.dart';
import 'package:pamoja/app/data/global_widgets/indicator.dart';
import 'package:pamoja/app/models/advert_model.dart';
import 'package:pamoja/app/modules/my_adverts/controllers/my_adverts_controller.dart';
import 'package:pamoja/app/routes/app_pages.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart';
import 'package:image_cropper/image_cropper.dart';
class UploadBlogController extends GetxController {
TextEditingController title = TextEditingController();
TextEditingController description = TextEditingController();
TextEditingController location = TextEditingController();
TextEditingController category = TextEditingController();
TextEditingController price = TextEditingController();
TextEditingController phone = TextEditingController();
final FirebaseFunctions _functions = FirebaseFunctions();
File? imageFile;
Future<void> pickImage() async {
try {
ImagePicker _picker = ImagePicker();
await _picker.pickImage(source: ImageSource.gallery).then((value) async {
if (value != null) {
File? croppedFile = await ImageCropper().cropImage(
sourcePath: value.path,
aspectRatio: CropAspectRatio(ratioX: 1, ratioY: 1),
compressQuality: 100,
maxWidth: 700,
maxHeight: 700,
// saveCircleCroppedImage: true,
);
if (croppedFile != null) {
imageFile = croppedFile;
update();
}
}
});
} catch (e) {
showAlert("$e");
}
}
void createBlog() async {
if (title.text.isNotEmpty && description.text.isNotEmpty) {
if (imageFile != null && imageFile != "") {
Indicator.showLoading();
await _functions
.uploadBlog(
title.text,
description.text,
imageFile!,
price.text,
category.text,
location.text,
phone.text,
)
.then((value) {
Indicator.closeLoading();
showAlert("Your advert created sucessfully");
// Get.back();
Get.toNamed(Routes.HOME);
});
} else {
showAlert("Image is required");
}
} else {
showAlert("All fields are required");
}
}
void editBlog(BlogsModel model) async {
Indicator.showLoading();
if (title.text.isNotEmpty && description.text.isNotEmpty) {
if (imageFile == null) {
Map<String, dynamic> map = {
'title': title.text,
'description': description.text,
};
await _functions.editBlog(model.id, map).then((value) {
Get.toNamed(Routes.HOME);
showAlert("Your ads Updated Sucessfully");
});
} else {
String imageUrl = await _functions.uploadImage(imageFile!);
Map<String, dynamic> map = {
'title': title.text,
'description': description.text,
'img': imageUrl,
};
await _functions.editBlog(model.id, map).then((value) {
Get.toNamed(Routes.HOME);
showAlert("Your Advert Updated Sucessfully");
});
}
} else {
showAlert("All fields are required");
}
Indicator.closeLoading();
updateData();
}
void updateData() {
Get.back();
Get.toNamed(Routes.HOME);
if (Get.isRegistered<MyBlogsController>()) {
final controller = Get.find<MyBlogsController>();
controller.myBlogs = [];
Indicator.showLoading();
controller.getMyBlogData();
}
}
}
this i created reusable single-tone code for my entire app to pick media image or video. you can try or modify according your requirement.
// Dart imports:
import 'dart:io';
// Package imports:
import 'package:image_cropper/image_cropper.dart';
import 'package:image_picker/image_picker.dart';
// Project imports:
import 'package:app/utils/export_utils.dart';
class MediaPicker {
MediaPicker._();
static const supportedImageFormates = [".jpeg", ".png"];
static const supportedVedioFormates = [".mp4"];
static final picker = ImagePicker();
// Single image / video selection
static Future<File?> pickMedia({
required ImageSource source,
bool isVideo = false,
bool isEditing = false,
}) async {
try {
final pickMedia = !isVideo
? await picker.pickImage(source: source)
: await picker.pickVideo(source: source);
if (pickMedia != null) {
return isEditing
? await editImage(file: File(pickMedia.path))
: File(pickMedia.path);
} else {
return null;
}
} catch (ex) {
"Pick Media error: $ex".printLog();
return null;
}
}
static Future<File> editImage({required File file}) async {
final CroppedFile? croppedFile = await ImageCropper().cropImage(
sourcePath: file.path,
uiSettings: [
AndroidUiSettings(
toolbarTitle: 'Cropper',
toolbarColor: ColorConst.themePrimaryColor,
toolbarWidgetColor: ColorConst.white,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false,
),
IOSUiSettings(
title: 'Cropper',
),
],
);
if (croppedFile != null) {
return File(croppedFile.path);
} else {
return file;
}
}
}
Usage add call method on button tap with Future & async method
Future<void> btnPickImageTap() async {
final File? selectImageFile = await MediaPicker.pickMedia(
source: ImageSource.gallery,
isEditing: true, // Default false
);
}
source: ImageSource.camera - to pick image from camera.
isEditing: false - avoid image cropping functionality.
isVideo: to pick video from gallery / camera.
Make sure following permission added for both platforms
Andriod- AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA"/> //Camera
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> // Read Storage
iOS Runner/info.plist
<key>NSCameraUsageDescription</key>
<string>App require camera permission to update profile pic</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>App require gallery permission to update profile pic</string>
As package mentioned in image_cropper add bellow code in AndroidManifest.xml under <applcaiton> TAG
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="#style/Theme.AppCompat.Light.NoActionBar"/>
I modified it following your instruction it worked. The following is a sample modification
Future<void> pickImage() async {
try {
ImagePicker _picker = ImagePicker();
await _picker.pickImage(source: ImageSource.gallery).then((value) async {
if (value != null) {
imageFile = File(value.path);
showAlert(imageFile.toString());
editImage(imageFile: imageFile);
// cropImage(imageFile);
} else {
showAlert("No image selected");
}
});
} catch (e) {
showAlert("$e");
}}
Future<void> editImage({required File? imageFile}) async {
final File? croppedFile = await ImageCropper().cropImage(
sourcePath: imageFile!.path,
androidUiSettings: AndroidUiSettings(
toolbarTitle: 'Advert Image',
toolbarColor: Colors.green.shade400,
toolbarWidgetColor: Colors.white,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false,
),
iosUiSettings: IOSUiSettings(
title: 'Cropper',
),
);
if (croppedFile != null) {
imageFile = File(croppedFile.path);
update();
} else {
// update();
}}
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;
});
}
}
whenever i want to make a document in firestore it wo't let me , i think its something that i did with riverpod and with hooks
here is the code :
onPressed: () async {
currentOrganization.when(
data: (organization) async {
_post.value = _post.value
.copyWith(creator: organization);
print(_post.value);
String imageid = uuid.v4();
pickedImage = await ImagePicker()
.getImage(
source: ImageSource.gallery,
maxWidth: 1920,
maxHeight: 1200,
imageQuality: 80);
Reference reference = FirebaseStorage
.instance
.ref()
.child("$imageid");
UploadTask uploadTask = reference
.putFile(File(pickedImage.path));
await uploadTask.then((res) async {
imageUrl = await reference
.getDownloadURL();
});
_post.value = _post.value
.copyWith(picture: imageUrl);
},
loading: () =>
const CircularProgressIndicator(),
error: (error, stack) => Center(
child: Text("$error"),
));
},
),
),
GestureDetector(
onTap: () async {
context
.read(createPostUSeCaseProvider)
.execute(CreatePostUseCaseInput(
uuid.v4(),
_post.value.description,
_post.value.title,
_post.value.creator,
_post.value.likes,_post.value.picture))
.then(
(result) => result.fold(
(failure) {
print('FAILURE: $failure');
toast("Please try again");
},
(unit) {
toast(" successfully");
},
),
);
},
when i delete the currentOrganizationProvider everything works like charm
here is the
UseCase
import 'package:dartz/dartz.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:takaful/application/core/use_cases/i.use_case.dart';
import 'package:takaful/application/post/use_case/create_post/create_post.input.dart';
import 'package:takaful/application/providers/post.repository.provider.dart';
import 'package:takaful/domain/core/i.failure.dart';
import 'package:takaful/domain/model/post.dart';
import 'package:takaful/domain/post/i.post.repository.dart';
final createPostUSeCaseProvider = Provider((ref) =>
CreatePostUseCase(postRepository: ref.watch(postRepositoryProvider)));
class CreatePostUseCase implements IUseCase<CreatePostUseCaseInput, Unit> {
final IPostRepository _postRepository;
CreatePostUseCase({IPostRepository postRepository})
: _postRepository = postRepository;
#override
Future<Either<IFailure, Unit>> execute(input) async {
return await _postRepository.createPost(
description: input.discreption,
model: input.model,
id: input.id,
title: input.title,
likes: input.likes,
picture: input.picture);
}
}
and the
infrastructure code :
Future<Either<UserFailures, Unit>> createPost({String id, String title, String description, OrganizationModel model, int likes,String picture}) async{
try {
await _firestore.collection(collection).doc().set({
"id":id,
"title":title,
"description":description,
"creator":model,
"likes":likes,
"picture":picture
});
return right(unit);
} catch (error) {
return left(UserFailures.serverError());
}
}
when i delete the the provider everything works , any idea , and i need the model !
I've copied the same code from file_picker package docs, but it keeps giving me a null value for all file details, here is the code I've copied
FilePickerResult result = await FilePicker.platform.pickFiles();
if(result != null) {
PlatformFile file = result.files.first;
print(file.name);
print(file.bytes);
print(file.size);
print(file.extension);
print(file.path);
}
The file name, bytes, size, extension and path are all giving a null value. Anyone know what is the reason for that ?
I've tried to upload a pdf, png, jpg, doc and get the same null value for all of them.
I'm using the latest version of this:
https://pub.dev/packages/file_picker
void _openFileExplorer() async {
File _pickedFile;
FilePickerResult _filePickerResult;
setState(() {
_isLoading = true;
});
try {
_filePickerResult = await FilePicker.platform.pickFiles(
type: FileType.any,
allowedExtensions: (_extension?.isNotEmpty ?? false)
? _extension?.replaceAll(' ', '')?.split(',')
: null);
} on PlatformException catch (e) {
print("Unsupported operation" + e.toString());
}
if (_filePickerResult != null) {
setState(() {
_pickedFile = File(_filePickerResult.files.single.path);
});
}
if (!mounted) return;
{
Flushbar(
showProgressIndicator: true,
progressIndicatorBackgroundColor: Colors.blueGrey,
title: 'Status:',
message: 'File loaded: $_pickedFile',
duration: Duration(seconds: 3),
backgroundColor: Colors.green,
)
..show(context);
}
setState(() {
_isLoading = false;
});
}