how I can add multiple images and store them in an array in firebase ?
every container has a + button so the user can add single image per container then I WANT TO STORE them in my firebase
any help would be greatly appreciated ^^
what you are showing in your image is fbCloudStore which is use to store information in json structure.
To store the images you may use fbStorge.
here's an snippet I use on my project:
Future<String?> uploadFile({
required FilePickerResult file,
required String fileName,
required FirebaseReferenceType referenceType,
}) async {
try {
final ref = _getReference(referenceType);
final extension = path.extension(file.files.first.name);
final _ref = ref.child(fileName + extension);
late UploadTask uploadTask;
if (kIsWeb) {
uploadTask = _ref.putData(file.files.first.bytes!);
} else {
uploadTask = _ref.putFile(File(file.files.single.path!));
}
var url;
await uploadTask.whenComplete(
() async => url = await uploadTask.snapshot.ref.getDownloadURL());
print(url);
return url;
} on FirebaseException catch (_) {
print(_);
}
}
Note that I'm returning the URL of fbStorage in order to associate it with fbCloudStorage
final url =
await FirebaseStorageSer.to.uploadFile(
file: result,
fileName: STORAGE_USER_PROFILE_PICTURE,
referenceType: FirebaseReferenceType.user,
);
if (url != null) {
await FirebaseAuthSer.to
.updateUserProfile(photoUrl: url);
}
FirebaseReferenceType.user is just a simple enum to simplify ref targets.
Related
To upload images for an object created by a user I store the images (selected by the user) in an array 'imagesList' as a File. When the user clicked upload (whole object) the following method saves the data on firebase:
TextButton(
onPressed: () async {
await uploadImage();
await jobService.createJob(Job(
titleTextEditorController.text.trim(),
category,
false,
false,
finalImageList));
},
child: Text('upload')),
The List finalImageList is filled in the first method 'uploadImage()'. I sourced it out in another method to get the await statement. The Code:
uploadImage() async {
for (int i = 0; i < imageList.length; i++) {
_imageFile = imageList[i];
String fileName = Path.basename(_imageFile!.path);
Reference reference =
FirebaseStorage.instance.ref().child('uploads/$fileName');
firebase_storage.SettableMetadata(
contentType: 'image/jpeg',
customMetadata: {'picked-file-path': fileName});
UploadTask uploadTask = reference.putFile(_imageFile!);
uploadTask.whenComplete(() async {
try {
imageUrl = await reference.getDownloadURL();
print('imageUrl' + imageUrl);
finalImageList.add(imageUrl);
} catch (onError) {
print("Upload Error");
}
});
await Future.value(uploadTask)
.then((value) => {print('Upload file path ${value.ref.fullPath}')})
.onError((error, stackTrace) =>
{print('Upload file path error ${error.toString()}')});
}
}
But the method is not fast enough to store the imageUrl's in finalImageList, so the Images is online but its not connected to the object in firebase. Is there a possibility to upload it immediately or the save the imageUrl correctly? Or is my code just in the wrong order?
The FlutterFire UploadTask class extends Future, which means that you can use await on it to wait until the upload is done.
That means you can write your code much simpler as:
await reference.putFile(_imageFile!);
imageUrl = await reference.getDownloadURL();
finalImageList.add(imageUrl);
print('Upload file path ${value.ref.fullPath}')
With this change, your uploadImage will only complete after the download URL was added to finalImageList.
I am working on a flutter project in which user is supposed to create some scripts and by typing them in text and then flutter_tts library is supposed to convert them to audio file which works fine for that time being but I want to save that file into firebase storage for later user. I have tried the following code but it just saves blank audio file in the firebase storage. Any kind of help will be appreciated.
The code I have tried is:
final FlutterTts _flutterTts = FlutterTts();
late var fileName;
/// creation of audio script
Future createAudioScript(
String name,
String script,
String firebasepath,
) async {
await _flutterTts.setLanguage("en-US");
await _flutterTts.setSpeechRate(1.0);
await _flutterTts.setVolume(1.0);
await _flutterTts.setPitch(1.0);
await _flutterTts.setVoice(
{"name": "en-us-x-tpf-local", "locale": "en-US"},
);
await _flutterTts.speak(script);
fileName = GetPlatform.isAndroid ? '$name.wav' : '$name.caf';
print('FileName: $fileName');
var directoryPath =
"${(await getApplicationDocumentsDirectory()).path}/audio/";
var directory = Directory(directoryPath);
if (!await directory.exists()) {
await directory.create();
print('[INFO] Created the directory');
}
var path =
"${(await getApplicationDocumentsDirectory()).path}/audio/$fileName";
print('[INFO] path: $path');
var file = File(path);
if (!await file.exists()) {
await file.create();
print('[INFO] Created the file');
}
await _flutterTts.synthesizeToFile(script, fileName).then((value) async {
if (value == 1) {
print('generated');
var file = File(
'/storage/emulated/0/Android/data/com.solution.thriving/files/$fileName',
);
print(file);
moveFile(file, path, '$firebasepath/$fileName').then((value) {
print('move file: $value');
_app.link.value = value;
print('link: ${_app.link.value}');
});
}
});
}
/// move file from temporary to local storage and save to firebase
Future<String> moveFile(
File sourceFile,
String newPath,
String firebasePath,
) async {
String audioLink = '';
print('moved');
await sourceFile.copy(newPath).then((value) async {
print('value: $value');
await appStorage.uploadAudio(value, fileName, firebasePath).then((audio) {
print(audio);
audioLink = audio;
return audioLink;
});
}).whenComplete(() async {
customToast(message: 'Audio has been generated successfully.');
});
return audioLink;
}
After spending whole day and with the help of a friend, I finally managed to figure out the issue which was being caused because I was using synthesizeToFile() and speak() functions at the same time, which I managed to resolved the issue by changing my code to the following code snippet.
final FlutterTts _flutterTts = FlutterTts();
late var fileName;
/// converting text to speech
Future createAudioScript(
String name,
String script,
String firebasepath,
) async {
await _flutterTts.setLanguage("en-US");
await _flutterTts.setSpeechRate(1.0);
await _flutterTts.setVolume(1.0);
await _flutterTts.setPitch(1.0);
await _flutterTts.setVoice(
{"name": "en-us-x-tpf-local", "locale": "en-US"},
);
if (GetPlatform.isIOS) _flutterTts.setSharedInstance(true);
// await _flutterTts.speak(script);
fileName = GetPlatform.isAndroid ? '$name.wav' : '$name.caf';
log('FileName: $fileName');
await _flutterTts.synthesizeToFile(script, fileName).then((value) async {
if (value == 1) {
log('Value $value');
log('generated');
}
});
final externalDirectory = await getExternalStorageDirectory();
var path = '${externalDirectory!.path}/$fileName';
log(path);
saveToFirebase(path, fileName, firebasPath: '$firebasepath/$name')
.then((value) => {log('Received Audio Link: $value')});
}
/// saving converted audio file to firebase
Future<String> saveToFirebase(String path, String name,
{required String firebasPath}) async {
final firebaseStorage = FirebaseStorage.instance;
SettableMetadata metadata = SettableMetadata(
contentType: 'audio/mpeg',
customMetadata: <String, String>{
'userid': _app.userid.value,
'name': _app.name.value,
'filename': name,
},
);
var snapshot = await firebaseStorage
.ref()
.child(firebasPath)
.putFile(File(path), metadata);
var downloadUrl = await snapshot.ref.getDownloadURL();
print(downloadUrl + " saved url");
return downloadUrl;
}
What I want to do: Upload a file and a video with Firebase Storage 0.5.0 and return url.
What current problem is: I can upload file and image with Firebase storage 0.5.0, but I can't return url. I also see my file and video uploaded in Firebase storage in Firebase console.
My code:
Future<String> _uploadFile(Reference ref, File file,
[SettableMetadata metadata]) async {
UploadTask uploadTask = ref.putFile(file, metadata);
uploadTask.whenComplete(() async {
try {} catch (onError) {
print("Error");
}
});
final url = await ref.getDownloadURL();
return url;
}
Future<String> uploadVideo(File video,
{String refName, SettableMetadata metadata}) async {
metadata = SettableMetadata(contentType: 'video/mp4');
final name = refName != null ? refName : path.basename(video.path);
final ref = _VideoRef.child(name);
return _uploadFile(ref, video, metadata);
}
Future<File> downloadImage(String imageUrl, String savePath) async {
final ref = _storage.ref(imageUrl);
var file = File(savePath);
await ref.writeToFile(file);
return file;
}
What the console told me:
FirebaseException (Firebase_storage/object-not-found). No object exist in desired reference.
How do I fix this?
Try the following:
uploadTask.whenComplete(() async {
try {
url = await ref.getDownloadURL();
} catch (onError) {
print("Error");
}
});
When the future completes, call getDownloadURL() to get the url.
I have a form that have images to upload , when the user try to press on "Submit" button i'm trying to upload list of images to firestore and get all of its URLs and then submit a form to "x" collection in firebase but the writing on "x" collocation done before upload the images and get it's URLs.
I thinks the problem with (async,await).
Appreciate to help me.
List<File> imagePaths= new List() ;
List<String> imageURL= new List() ;
Future<FirebaseUser> getUser() async {
return await _auth.currentUser();
}
Future<void> uploadPic(File _image) async {
String fileName = basename(_image.path);
StorageReference firebaseStorageRef =
FirebaseStorage.instance.ref().child(Random().nextInt(10000).toString()+fileName);
StorageUploadTask uploadTask = firebaseStorageRef.putFile(_image);
var downloadURL = await(await uploadTask.onComplete).ref.getDownloadURL();
var url =downloadURL.toString();
imageURL.add(url); // imageURL is a global list that suppose to contain images URLs
print("\n ---------------------------\n downloadURL :"+ url);
print("\n ---------------------------\n imageURL :"+ imageURL.toString());
}
Submit(BuildContext context) {
//imagePaths is list of file
imagePaths.add(Front_image);
imagePaths.add(Back_image);
imagePaths.forEach((x) => {
uploadPic(x)
});
getUser().then((user) {
crudObj.addNew({
'uid': user.uid,
'name': name,
'images':imageURL,
}).then((result) {
Navigator.pop(context);
}).catchError((e) {
print(e);
});
});
}
You should call your Submit only once your upload task is complete. I would recommend implementing something like this:
Stream uploadImageToFirebaseStorage(File image, String fullPath) {
final StorageReference firebaseStorageRef =
FirebaseStorage.instance.ref().child(fullPath);
StorageUploadTask task = firebaseStorageRef.putFile(image);
return task.events;
}
And then listen to this Stream and only then submit:
uploadImageToFirebaseStorage(
image, 'path/imagename.jpg'
).listen((data) async {
StorageTaskEvent event = data;
if (data.type == StorageTaskEventType.success) {
String downloadUrl = await event.snapshot.ref.getDownloadURL();
await Submit(title, imageUrl: downloadUrl);
return true;
}
if (data.type == StorageTaskEventType.failure) return false;
});
Please take note that I did not re-write your code, I am sharing a possible implementation.
I would like to retrieve the Download URL of a private image in firbase storage.
Hi have tried many of the suggestions on the site, but all of them end up in the same result.
I have tried the following code:
getImageNow() async {
StorageReference ref =
FirebaseStorage.instance.ref().child("/1.jpg");
String url = (await ref.getDownloadURL()).toString();
return url;
}
It works when i print the url inside the function, but when i try to call print(getImageNow())to get the url, i just get "Instance of 'Future<dynamic>'"
UPDATE*************
In the end i am trying to get somthing like this:
return Image.network(
getImageNow(),
);
But i can not get it to work with async.
Since getImageNow() is asynchronous (as indicated by the async keyword), you will need to use await to make the calling code wait for the result:
print(await getImageNow())
What await does here is that it essentially unwraps the Future and is equivalent to:
getImageNow().then((value) => print(value));
this is how i upload and get the download url
this part is how i get image from picker
Future getImage() async {
var image = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
_image = image;
print('Image Path $_image');
});
}
then i upload it
Future uploadPic(BuildContext context) async {
String fileName = basename(_image.path);
StorageReference firebaseStorageRef = FirebaseStorage.instance.ref().child(fileName);
StorageUploadTask uploadTask = firebaseStorageRef.putFile(_image);
StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
final String url = (await taskSnapshot.ref.getDownloadURL());
print('URL Is $url');
}
hope it will help someone