I sucessfully Get to pick multiple images from gallery and decided to try uploading to firebase and as well retrieving the image URL. after calling the upload it requested a pass a parameter which i did but it gives an error "The argument type 'List' can't be assigned to the parameter type 'Asset" when i try to specify the index of the parameter i passed it only Saves that image with that particular index.
i also tried a for loop but still it saves only one image and return its url.
How do i get to Upload all the images
Below is how i load the images.
Future<void> loadAssets() async {
List<Asset> resultList = <Asset>[];
resultList = await MultiImagePicker.pickImages(
maxImages: 300,
enableCamera: true,
selectedAssets: images,
cupertinoOptions: const CupertinoOptions(takePhotoIcon: "chat"),
materialOptions: const MaterialOptions(
actionBarColor: "#abcdef",
actionBarTitle: "Example App",
allViewTitle: "All Photos",
selectCircleStrokeColor: "#000000",
));
if (!mounted) return;
setState(() {
images = resultList;
});
}
then i upload the image using the following snippet
Future UploadImage(Asset asset) async {
String fileName = popop;
ByteData byteData = await asset.getByteData();
List<int> imageData = byteData.buffer.asUint8List();
Reference ref = FirebaseStorage.instance.ref().child(fileName);
UploadTask uploadTask = ref.putData(Uint8List.fromList(imageData));
TaskSnapshot snapshot= await uploadTask;
String url= await snapshot.ref.getDownloadURL();
if (kDebugMode) {
print(url);
}
/// After this Update user Profile or add url to collection
return url;
}
used the below code to call/upload a single image out of the list
RaisedButton(
child: const Text("Save Image"),
onPressed: () => UploadImage(images[0]),
),
How to i get to upload all images.
i even tried the for loop below
for(int i=o; i<images.length;i++){
UploadImages(images[i]);
}
But only uploaded a single image
You can iterate over your images like this for example:
final fileNames = <String>[];
for (final image in images) {
final fileName = await uploadImage(image);
fileNames.add(fileName);
}
Not sure whether you really need to call getDownloadUrl() (depends on your use case), but this method creates a public and long-lived url.
If you just want to store a reference in Cloud Firestore for example, you can get the name / fullPath of the respective file from your TaskSnapshot in the uploadImage function as follows:
Future<String> UploadImage(Asset asset) async {
String fileName = popop;
ByteData byteData = await asset.getByteData();
List<int> imageData = byteData.buffer.asUint8List();
Reference ref = FirebaseStorage.instance.ref().child(fileName);
UploadTask uploadTask = ref.putData(Uint8List.fromList(imageData));
TaskSnapshot snapshot= await uploadTask;
// Assuming you are interested in the fullPath use snapshot.ref.fullPath
// For the name use snapshot.ref.name instead
return snapshot.ref.fullPath
}
Related
in my flutter app, the user picture is loaded by Cached Network image command, which gets its url by stream builder from firestore.
I am trying to add the functionality to the user of changing his pic by pressing on the pic as following:
Selecting his pic with image picker.
upload it to firebase storage.
updating firestore usercollection document with new image url.
I created the below code.
The problem is getDownloadURL() is not returning actual string, but "Instance of 'Future'".
so the new link stored in firestore is not correct to be used by Cached Network Image.
how can I get the actual URl String?
My Future Function Code:
Future ChangeProfilePic() async {
String newimageurl = "";
FirebaseStorage storage = FirebaseStorage.instance;
Reference ref =
storage.ref().child("ProfileImages/$globaluserid".toString());
CollectionReference userscollectionref =
FirebaseFirestore.instance.collection('UsersCollection');
final ImagePicker _picker = ImagePicker();
final XFile? image = await _picker.pickImage(source: ImageSource.gallery);
File imagefile = File(image!.path);
UploadTask uploadTask = ref.putFile(imagefile);
uploadTask.whenComplete(() {
newimageurl = ref.getDownloadURL().toString();
print("Image Uploaded");
userscollectionref
.doc(globaluserid)
.update({'User_image_link': newimageurl});
print("Link is Updated");
}).catchError((onError) {
print("Error");
print(onError);
});
}
Like many calls in your code `` is an asynchronous call, whose result won't be available immediately, so it returns a Future that will at some point contain the value. You can use await to wait for such a Future to complete and get its value, similar to what you already do in await _picker.pickImage.
await ref.getDownloadURL().toString();
Another change to consider is that putFile returns a Task, but that is actually also a Future, which means that you can await that too.
Combining these two fact, you can simplify your code to:
final XFile? image = await _picker.pickImage(source: ImageSource.gallery);
File imagefile = File(image!.path);
await ref.putFile(imagefile);
newimageurl = (await ref.getDownloadURL()).toString();
print("Image Uploaded");
userscollectionref
.doc(globaluserid)
.update({'User_image_link': newimageurl});
print("Link is Updated");
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;
}
I cant get a valid URL to retrieve in my method when images are linked to CloudFirestore from Storage in Firebase:
Future uploadImage(BuildContext context) async {
String fileName = basename(_imageFile.path);
Reference firebaseStorageRef =
FirebaseStorage.instance.ref().child('ifprofile/$fileName');
UploadTask uploadTask = firebaseStorageRef.putFile(_imageFile);
TaskSnapshot taskSnapshot = await uploadTask.whenComplete(() {
var firebaseUser = FirebaseAuth.instance.currentUser;
FirebaseFirestore.instance.collection('/userProfile').add({
"imageUrl": _imageFile.path,
});
FirebaseFirestore.instance
.collection('/influencerUser')
.doc(firebaseUser.uid)
.update({
// All fields you want to update in a document
'imageUrl': IfUserProfile.imageUrl,
});
// Finish to Link images to Cloud Firestore
});
taskSnapshot.ref
.getDownloadURL()
.then((value) => print("Image uploaded: $value"));
}
into cloud firestore I get URL like this:
/data/user/0/it.test.testapp/cache/image_picker5217031945896769637.jpg
any input please?
try to modify ur code a but like this
final url = await taskSnapshot.ref
.getDownloadURL();
then take that url and put it in your firestore db
here is some code
final storageRef = FirebaseStorage.instance.ref('$folderName/$imagename');
final uploadTaskSnapshot = await storageRef.put(image).future;
final imageUri = await uploadTaskSnapshot.ref.getDownloadURL();
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();
}
I am using this package to get mutliple images from gallery and it return a list of Asset, now I want to send it to server, I am use FormDate but there image path required.
Is there any other way to send Asset image to server?
how to convert List<Asset> to List<File>.
how to get image path from Asset
Or any other method to done this task(Choose mutliple images from storage and send them to server).
List<Asset> images = List<Asset>();
FormData imageFormData = FormData.fromMap({
"files": images.map((image) async {
return await MultipartFile.fromFile('assets/${image.name}', filename: image.name);
}).toList(),
});
Here is the solution.
List<Asset> images = List<Asset>();
List<MultipartFile> multipart = List<MultipartFile>();
for (int i = 0; i < images.length; i++) {
var path = await FlutterAbsolutePath.getAbsolutePath(images[i].identifier);
multipart.add(await MultipartFile.fromFile(path, filename: 'myfile.jpg'));
}
FormData imageFormData = FormData.fromMap({"files": multipart,});
Make use of flutter_absolute_path package.
add flutter_absolute_path: ^1.0.6 in pubsec.yaml
This will convert file path from this format : “content://media/external/images/media/5275”
To this format (absolute format)
"/storage/emulated/0/DCIM/Camera/IMG_00124.jpg”
Then make use of this method:
Future<List> imagePicker() async{
List<Asset> assetArray = [];
List <File> fileImageArray = [];
try {
assetArray = await MultiImagePicker.pickImages(
maxImages: 300,
enableCamera: true,
selectedAssets: assetArray ,
cupertinoOptions: CupertinoOptions(takePhotoIcon: "chat"),
materialOptions: MaterialOptions(
actionBarColor: "",
actionBarTitle: "ImagePicker",
allViewTitle: "All Photos",
useDetailsView: false,
selectCircleStrokeColor: "#000000",
),
);
}on Exception catch (e) {
print( e.toString());
}
assetArray.forEach((imageAsset) async {
final filePath = await FlutterAbsolutePath.getAbsolutePath(imageAsset.identifier);
File tempFile = File(filePath);
if (tempFile.existsSync()) {
fileImageArray.add(tempFile);
}
});
return fileImageArray;
}
I think you can read assets file as file before sending over as below:
File imageFile = File('yourAssetsUriPath.jpg');
yourAssetsUriPath is pointing to your assets folder by default, so you can simply put your filename in the path.
As for http post it, you can refer here