How to load images from Firebase cloud storage to flutter - firebase

I have stored my images on Firebase Cloud Storage and I want to put them on the icon. I want a function to pass the name of the image and grab that image URL for me but this approach doesn't work for me.
Future<String> downloadURLExample(product) async {
String downloadURL = await firebase_storage.FirebaseStorage.instance
.ref('product_images/fruits/$product.jfif')
.getDownloadURL();
return downloadURL;
}
String returnImg(String product){
downloadURLExample(product).then((value) => {
imgURL = value
});
return imgURL;
}
I call my function as so:
returnImg(apple)

You should use await for the async function:
await downloadURLExample(product);
This is the full example:
Future<String> downloadURLExample(product) async {
String downloadURL = await firebase_storage.FirebaseStorage.instance
.ref('product_images/fruits/$product.jfif')
.getDownloadURL();
return downloadURL;
}
String returnImg(String product) {
String imgURL = await downloadURLExample(product);
return imgURL;
}
And you could call the function as follows:
returnImg('apple');
You can read a bit more about async functions here.

Related

Is there any way to save flutter_tts file to firebase storage?

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;
}

Flutter Firebase async query not retrieving data inside a stream function

I am trying to query a User from firebase within another query but for some reason but I can't get the code to work
The function the wont run is await usersRef.doc(uid).get(); and can be found here:
static getUserData(String uid) async {
return await usersRef.doc(uid).get();
}
static DirectMessageListModel getDocData(QueryDocumentSnapshot qdoc, String uid) {
Userdata postUser = Userdata.fromDoc(getUserData(uid));
return DirectMessageListModel.fromDoc(qdoc, postUser);
}
static DirectMessageListModel fromDoc(QueryDocumentSnapshot doc, Userdata altUser) {
return DirectMessageListModel(
doc['chatId'],
doc['lastMsgContent'],
doc['lastMsgType'],
altUser
);
}
parent function:
Stream<List<DirectMessageListModel>> getMeassageList(){
var snaps = FirebaseFirestore.instance.collection('directMessages').where('users', arrayContains: userdata!.uid).snapshots();
List<String> usersListElement = [];
return snaps.map((event) { return event.docs.map((e) {
usersListElement = [e.get('users')[0], e.get('users')[1]];
usersListElement.remove(userdata!.uid);
return DirectMessageListModel.getDocData(e, usersListElement.first);
}).toList();
});
}
You forgot to wait for the future getUserData(uid) to complete.
Try this:
static Future<DocumentSnapshot<Object>> getUserData(String uid) async {
return await usersRef.doc(uid).get();
}
static DirectMessageListModel getDocData(
QueryDocumentSnapshot qdoc,
String uid,
) async {
Userdata postUser = Userdata.fromDoc(await getUserData(uid)); // await here
return DirectMessageListModel.fromDoc(qdoc, postUser);
}
..
// parent function.
// Also wait for the future in the parent function.
// UPDATE BELOW! Define the parent function like this:
Stream<List<Future<DirectMessageListModel>>> getMeassageList() {
var snaps = FirebaseFirestore.instance
.collection('directMessages')
.where('users', arrayContains: userdata!.uid)
.snapshots();
List<String> usersListElement = [];
return snaps.map((event) {
return event.docs.map((e) async {
usersListElement = [e.get('users')[0], e.get('users')[1]];
usersListElement.remove(userdata!.uid);
return await DirectMessageListModel.getDocData(e, usersListElement.first);
}).toList();
});
}
NB: You are fetching user data (either sender/receiver) for each message in directMessages collection. It might be better to store just sender/receiver name in directMessages collection and simply display that. Then if the user clicks on a message, you can then fetch the full sender/receiver data.

Flutter Firebase Storage 0.5.0 upload file and video error

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.

Upload multi images to firestore using flutter and get it's download URLs and save all of URLs to firebase

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.

How to get the download URL from firebase with flutter?

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

Resources