This is my code -
Future uploadImage() async {
var randomno = Random(25);
final StorageReference firebaseStorageRef = FirebaseStorage.instance
.ref()
.child('profilepics/${randomno.nextInt(5000).toString()}.jpg');
StorageUploadTask task = firebaseStorageRef.putFile(selectedImage);
task.future.then((value) {
setState(() {
userManagement
.updateProfilePic(value.downloadUrl.toString())
.then((val) {
setState(() {
profilePicUrl = value.downloadUrl.toString();
isLoading = false;
});
});
});
}).catchError((e) {
print(e);
});
}
This is the error it gives -
The getter 'future' isn't defined for the type 'StorageUploadTask'.
Try importing the library that defines 'future', correcting the name to the name of an existing getter, or defining a getter or field named 'future'.
Although i have already imported dart:async and dart:io
Please help, thanks
StorageUploadTask doesnt have a property called future, you have to use onComplete the following:
final StorageReference firebaseStorageRef = FirebaseStorage.instance
.ref()
.child('profilepics/${randomno.nextInt(5000).toString()}.jpg');
StorageUploadTask task = firebaseStorageRef.putFile(selectedImage);
task.onComplete.then((value) {
setState(() {
userManagement
.updateProfilePic(value.ref.getDownloadURL().toString())
.then((val) {
setState(() {
profilePicUrl = value.ref.getDownloadURL().toString();
isLoading = false;
});
});
});
https://github.com/FirebaseExtended/flutterfire/blob/master/packages/firebase_storage/lib/src/upload_task.dart#L28
now 'onComplete' is also showing error
The getter 'onComplete' isn't defined for the type 'UploadTask'.
Try importing the library that defines 'onComplete', correcting the name to the name of an existing getter, or defining a getter or field named 'onComplete'.
Related
void validateAndUpload() async {
if (_formKey.currentState.validate()) {
setState(() => isLoading = true);
if (_image1 != null) {
if (selectedSizes.isNotEmpty) {
String imageUrl1;
final FirebaseStorage storage = FirebaseStorage.instance;
final String picture1 =
"${DateTime.now().millisecondsSinceEpoch.toString()}.jpg";
StorageUploadTask task1 =
storage.ref().child(picture1).putFile(_image1);
task1.onComplete.then((snapshot1) async {
imageUrl1 = await snapshot1.ref.getDownloadURL();
_productServices.uploadProduct(
productName: productNameController.text,
brandName: _currentBrand,
details: detailController.text,
category: _currentCategory,
quantity: int.parse(quantityController.text),
size: selectedSizes,
picture: imageUrl1,
feature: feature,
sale: sale,
price: double.parse(priceController.text));
_formKey.currentState.reset();
The getter 'onComplete' isn't defined for the type 'UploadTask'. (Documentation) Try importing the library that defines 'onComplete', correcting the name to the name of an existing getter, or defining a getter or field named 'onComplete'.
That error seems correct. Did you mean whenComplete?
I typically prefer to simply await the task though:
var ref = storage.ref().child(picture1);
await ref.putFile(_image1);
imageUrl1 = await ref.getDownloadURL();
...
final ref = FirebaseStorage.instance
.ref("${DateTime.now().millisecondsSinceEpoch.toString()}.jpg");
var uploadEvent = ref.putFile(_image1!);
String imageUrl = await (await uploadEvent.whenComplete(() => null))
.ref
.getDownloadURL();
I'm new to flutter and trying to send image via chat section. I'm getting 2 errors in my code. how can I solve this. appreciate your help on this.
error: The argument type 'String' can't be assigned to the parameter
type 'List'.
error: 2 positional argument(s) expected, but 1 found. )
Complete Reproducible Code on DartPad
final FirebaseAuth _auth = FirebaseAuth.instance;
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
File? imageFile;
Future getImage() async {
ImagePicker _picker = ImagePicker();
await _picker.pickImage(source: ImageSource.gallery).then((xFile) {
if (xFile != null) {
imageFile = File(xFile.path);
uploadImage();
}
});
}
Future uploadImage() async {
String fileName = Uuid().v1();
int status = 1;
await _firestore
.collection('chatdetail')
.doc(friendUid)
.collection('chats')
.doc(fileName)
.set({
"sendby": _auth.currentUser!.displayName,
"message": "",
"type": "img",
"time": FieldValue.serverTimestamp(),
});
var ref =
FirebaseStorage.instance.ref().child('images').child("$fileName.jpg");
//error in ImageFile
var uploadTask = await ref.putFile(imageFile!).catchError((error) async {
await _firestore
.collection('chatdetail')
.doc(friendUid)
.collection('chats')
.doc(fileName)
.delete();
status = 0;
});
if (status == 1) {
String imageUrl = await uploadTask.ref.getDownloadURL();
await _firestore
.collection('chatdetail')
.doc(friendUid)
.collection('chats')
.doc(fileName)
.update({"message": imageUrl});
print(imageUrl);
}
}
Replace import 'dart:html'; with 'import 'dart:io';'. You just imported the wrong package. File you want is from dart:io not dart:html.
I have made a function to upload three images to firebase storage. I have been doing it with the help of a tutorial. Since the tutorial uses old version codes I am trying my maximum to change it to a newer version. In the tutorial, it uses onComplete method to get the task snapshot. But in the pub.dev docs it is said that these methods have been removed and their is an exception Like this(
BREAKING: isCanceled, isComplete, isInProgress, isPaused and isSuccessful have now been removed. Instead, you should subscribe to the stream (for paused/progress/complete/error events) or the task Future for task completion/errors.)
please tell what does this mean and how can I change my below code according to it.
there is an error showing in the place where I type onComplete
void validateAndUpload() async{
if (_formKey.currentState.validate()) {
if (_image1 != null && _image2 != null && _image3 != null) {
if (selectedSizes.isNotEmpty) {
String imageUrl1;
String imageUrl2;
String imageUrl3;
final FirebaseStorage storage = FirebaseStorage.instance;
final String picture1 =
'1${DateTime.now().millisecondsSinceEpoch.toString()}.jpg';
UploadTask task1 = storage.ref().child(picture1).putFile(_image1);
final String picture2 =
'2${DateTime.now().millisecondsSinceEpoch.toString()}.jpg';
UploadTask task2 = storage.ref().child(picture2).putFile(_image2);
final String picture3 =
'3${DateTime.now().millisecondsSinceEpoch.toString()}.jpg';
UploadTask task3 = storage.ref().child(picture3).putFile(_image3);
TaskSnapshot snapshot1 = await task1.onComplete.then((snapshot) => snapshot);
TaskSnapshot snapshot2 = await task1.onComplete.then((snapshot) => snapshot);
task3.onComplete.then((snapshot3) async{
imageUrl1 = await snapshot1.ref.getDownloadURL();
imageUrl2 = await snapshot2.ref.getDownloadURL();
imageUrl3 = await snapshot3.ref.getDownloadURL();
});
} else {
Fluttertoast.showToast(
msg: "Sizes cannot be Empty",
backgroundColor: Colors.red,
textColor: Colors.white);
}
} else {
Fluttertoast.showToast(
msg: "Images are not Filled",
backgroundColor: Colors.red,
textColor: Colors.white);
}
}
}
You are almost there! As the error says either you have to listen for the UploadTask streams or await for UploadTask to complete. For your case,
TaskSnapshot snapshot1 = await task1;
TaskSnapshot snapshot2 = await task2;
TaskSnapshot snapshot3 = await task3;
imageUrl1 = await snapshot1.ref.getDownloadURL();
imageUrl2 = await snapshot2.ref.getDownloadURL();
imageUrl3 = await snapshot3.ref.getDownloadURL();
For more ref - https://firebase.flutter.dev/docs/storage/usage/#handling-tasks
I have an app feature where the user picks images from his phone and then uploads them to Firebase Storage.
I thought that the upload process should be done in a separate isolate.
I keep getting an exception which I think is related to the Multi Image Picker package.
The exception is:
E/flutter (12961): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)]
Unhandled Exception: Exception: NoSuchMethodError: The getter
'defaultBinaryMessenger' was called on null.
When the user presses on the upload button, this method is called:
Future<void> _initIsolate() async {
ReceivePort receivePort = ReceivePort();
receivePort.listen(
(message) {
print(message.toString());
},
onDone: () => print('Done'),
onError: (error) => print('$error'),
);
await compute(
_function, // This function is called in the separate isolate
{
'sendingPort': receivePort.sendPort,
'images': images,
},
);
}
The _function method is as follows:
static void _function(Map<String, dynamic> parameterMap) async {
SendPort sendingPort = parameterMap['sendingPort'];
List<Asset> images = parameterMap['images'];
List<String> urls = [];
int index = 0;
images.forEach(
(image) async {
String url = await getDownloadUrl(image); // a helper method
urls.add(url);
sendingPort.send('Image number: $index uploaded');
index += 1;
},
);
final CollectionReference collectionRef = FirebaseFirestore.instance.collection('offers');
final user = CurrentUser.getCurrentUser();
await collectionRef.doc(user.uid).set(
{
'time': FieldValue.serverTimestamp(),
'urls': urls,
},
);
}
The helper method _getDownloadUrl is as follows:
Future<String> getDownloadUrl(Asset image) async {
String rannum = Uuid().v1();
final ByteData byteData = await image.getByteData(); // --> This produces a defaultBinaryMessenger
final List<int> imageData = byteData.buffer.asUint8List();
Reference reference = FirebaseStorage.instance.ref().child("offers/$rannum");
UploadTask uploadTask = reference.putData(imageData);
TaskSnapshot downloadUrl = await uploadTask.whenComplete(() => null);
Future<String> futureUrl = downloadUrl.ref.getDownloadURL();
return futureUrl;
}
The getByteData method is part of the multi_image_picker package.
The source code is:
Future<ByteData> getByteData({int quality = 100}) async {
if (quality < 0 || quality > 100) {
throw new ArgumentError.value(
quality, 'quality should be in range 0-100');
}
Completer completer = new Completer<ByteData>();
ServicesBinding.instance.defaultBinaryMessenger // --> Exception here. ServicesBinding.instance is null
.setMessageHandler(_originalChannel, (ByteData message) async {
completer.complete(message);
ServicesBinding.instance.defaultBinaryMessenger
.setMessageHandler(_originalChannel, null);
return message;
});
await MultiImagePicker.requestOriginal(_identifier, quality);
return completer.future;
}
Why is the ServicesBinding.instance null?
Since this method is working fine without using Isolates, does this have something to do with the isolates?
Im using this code.
The error message is the following:
error: The getter 'onComplete' isn't defined for the type 'UploadTask'. (undefined_getter at [chatneu] lib/Screens/HomeScreen.dart:289)
Future uploadFile() async {
try {
pr = new ProgressDialog(context);
await ImagePicker().getImage(
source: ImageSource.gallery).then((image) {
setState(() {
_image = image as File;
//klammern weg bei ImagePicker und .getImage zu Pickimage
});
});
await pr.show();
Reference storageReference = FirebaseStorage.instance.ref().child(
'${loggedInUser.uid}/UserProfille/${Path.basename(_image.path)}');
UploadTask uploadTask = storageReference.putFile(_image);
await uploadTask.onComplete;
print('File Uploaded');
storageReference.getDownloadURL().then((fileURL) {
setState(() {
FirebaseFirestore.instance.collection('Users').doc(loggedInUser.uid);
Map<String, String> data = {
'photoUrl': fileURL,
};
I'm not sure where you got the idea that there is a method called onComplete on the UploadTask. If you follow the example code in the documentation, you will see that you just await the UploadTask directly:
await storageReference.putFile(_image);
storageReference.getDownloadURL().then(...);
You might also want to review the docs on handling tasks.
onComplete does not have any more but there is different method is whenComplete may replace what you need.
await ref.putFile(image).whenComplete(() => doSomething());