Flutter Firebase Storage listAll - firebase

I'm trying to download all videos in firebase storage using .listAll(). In the forEach(), I'm getting the URL when I print the value, but its not adding it to my list. Am I doing something wrong?
final List<String> videoUrls = [];
final result = await FirebaseStorage.instance.ref().listAll();
result.items.forEach((Reference ref){
ref.getDownloadURL().then((value) {
print(value);
videoUrls.add(value);
});
});

Try this code. In this code snippet, get download URL task is done asynchronously.
final List<String> videoUrls = [];
final result = await FirebaseStorage.instance.ref().listAll();
result.items.forEach((Reference ref) async {
await ref.getDownloadURL().then((value) {
String val = value.toString();
print(val);
videoUrls.add(val);
});
});

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

How to add multiple images in flutter (firebase)

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.

How to get a Stream of download url in firebase flutter

i want to create a stream of firebase storage download link for all the images
firebase_storage.FirebaseStorage storage =
firebase_storage.FirebaseStorage.instance;
firebase_storage.Reference ref =
storage.ref().child('images');
firebase_storage.ListResult result = await ref.listAll();
result.items.forEach((firebase_storage.Reference ref) async* {
print('Found file: $ref');
yield (await ref.getDownloadURL()).toString();
});
}
the snapshot data is null
if i create with future it seems to work when i add all the urls in a list and give to listview builder
but i cant get each string through stream
I've had problems with ForEach and await getDownloadUrl(). Try using a for loop instead.
for (Reference refin result.items) async* {
print('Found file: $ref');
yield (await getDownloadUrl().toString());
}
First thing first create a instance of FirebaseStorage
final _firestorage = FirebaseStorage.instance;
after then we need ref. for get image from storage.
final ref = _firestorage.ref().child('image');
and then we can create image's url.
var imageURL = await ref.getDownloadURL();
and try this.
print(imageURL);
if you wanna get this codes into fully method:
String getImageURL(){
final _firestorage = FirebaseStorage.instance;
final ref = _firestorage.ref().child('image');
var imageURL = await ref.getDownloadURL();
if(imageURL != null){
return imageURL;
}else{
print("Couldn't load image");
}
}
Also you can get this image with StreamBuilder or FutureBuilder etc. for get more about FirebaseStorage check it out this documentation

How to load images from Firebase cloud storage to flutter

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.

How to get a single document data from Cloud_Firestore to my variable?

I have been trying to get a single data from Firestore. But I can't.
void _onPressed() async{
var firebaseUser = await FirebaseAuth.instance.currentUser();
var userData;
firestoreInstance.collection("users").document(firebaseUser.uid).get().then((value){
setState(){
userData = value.data
}
print('Value data = ${value.data}');
});
print('UserData = ${userData}');
}
Result:
Value data = { some data some data}
UserData = null
Why is my userData null? How do I solve this? I'm looking forward to hearing from you.
get() is asynchronous and returns immediately before the query is complete. then() is also asynchronous (as well as anything that returns a Future). Use await instead of then to pause your code until a result is available.
var snapshot = firestoreInstance.collection("users").document(firebaseUser.uid).get()
var userData = snapshot.data
print('UserData = ${userData}')
You have to do the following:
void _onPressed() async{
var userData;
var firebaseUser = await FirebaseAuth.instance.currentUser();
var result = await firestoreInstance.collection("users").document(firebaseUser.uid).get();
setState((){
userData = result.data;
});
}
Since get() is asynchronous then use await to wait for the result, after that you can call setState() which will rebuild the layout with the new data.
If you are using cloud_firestore: 0.14.0+ then use this code:
void _onPressed() async{
var userData;
var firebaseUser = FirebaseAuth.instance.currentUser;
var result = await FirebaseFirestore.instance.collection("users").doc(firebaseUser.uid).get();
setState((){
userData = result.data();
});
}
Since You put this line outside the then function.
print('UserData = ${userData}');
firestoreInstance.collection("users").document(firebaseUser.uid).get().then((value){
setState(){
userData = value.data
}
print('Value data = ${value.data}');
});
print('UserData = ${userData}'); //Since this line is outside the then function.
// This line will be execute before the then function(then function will execute after getting the data from firebase)

Resources