How to get a Stream of download url in firebase flutter - firebase

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

Related

Firebase returns null photoUrl

I am building a mock social media app that allows users upload profile pictures to create their profiles. I am building this app in flutter.
Right now, here's my uploadPic method:
Future uploadPic(BuildContext context) async{
String fileName = basename(_image.path);
FirebaseStorage storage = FirebaseStorage.instance;
var photoUrl;
Reference ref = storage.ref().child(fileName);
var storedImage = File(_image.path);
UploadTask uploadTask = ref.putFile(storedImage);
uploadTask.then((res) {
photoUrl = res.ref.getDownloadURL();
});
print("photo url -- $photoUrl");
await widget.user?.updatePhotoURL(photoUrl);
await FirebaseAuth.instance.currentUser?.updatePhotoURL(photoUrl);
}
I have added the right permissions in my firebase console to allow read and write to the database. I know this because when I check firebase storage, I see the pictures have been uploaded successfully. However, when I try to print the returned photo url (after the upload task completes), I get a null value. This is a problem when I try to access the photo in other areas in the app, because the user photoUrl in firebase is null.
Is there anything I am doing wrong concerning the upload of the pic to firebase?
Also, my terminal returns this: No App Check token for request.. I'm wondering if this has anything to do with the issue?
Any help would be greatly appreciated!
your problem is simple, it's exactly from here:
var photoUrl;
uploadTask.then((res) {
photoUrl = res.ref.getDownloadURL();
});
print(photoUrl); // null
the problem is you are trying to print photoUrl variable without waiting for the future uploadTask to finish its work which results null.
the solution is to wait for uploadTask future before printing the photoUrl variable:
var photoUrl;
await uploadTask.then((res) async {
photoUrl = await res.ref.getDownloadURL();
});
print(photoUrl);
the solution on your code:
Future uploadPic(BuildContext context) async{
String fileName = basename(_image.path);
FirebaseStorage storage = FirebaseStorage.instance;
var photoUrl;
Reference ref = storage.ref().child(fileName);
var storedImage = File(_image.path);
UploadTask uploadTask = ref.putFile(storedImage);
await uploadTask.then((res) async {
photoUrl = await res.ref.getDownloadURL();
});
print("photo url -- $photoUrl");
await widget.user?.updatePhotoURL(photoUrl);
await FirebaseAuth.instance.currentUser?.updatePhotoURL(photoUrl);
}

Define Firebase cloud storage path in flutter

I am having trouble defining path for Firebase cloud storage.
I would like it to be -
user id -> firestore doc id -> folder's name.
currently, I successfully save the images in this way.
class FirebaseStorageService {
final String imageName;
FirebaseStorageService({required this.imageName});
get imageFileName =>
imageName + DateTime.now().millisecondsSinceEpoch.toString();
//get firestore doc id
final postid = FirebaseFirestore.instance.collection('properties').doc().id;
//get user id
final String? userid = FirebaseAuth.instance.currentUser!.uid;
//! Upload gallery
Future<String> saveGalleryInCloudStorage({
required File file,
}) async =>
await upload(
file: file,
path: '$userid/$postid/Property Gallery/$imageFileName',
contentType: 'image/png');
/// Generic file upload for any [path] and [contentType]
Future<String> upload({
required File file,
required String path,
required String contentType,
}) async {
final storageReference = FirebaseStorage.instance.ref().child(path);
final uploadTask = storageReference.putFile(
file, SettableMetadata(contentType: contentType));
final snapshot = await uploadTask;
final downloadUrl = await snapshot.ref.getDownloadURL();
return downloadUrl;
}
}
However, the problem I am having is the postid (that is used in firebase cloud storage path) is not same with firestore doc id.
How do I make them to be the same?
Thanks in advance!!
.collection('properties').doc()
the doc is empty hence firebase generates an auto id.
What you can do is Create an empty doc get a doc id, use the id to save the file, and when saving your firestore doc just update the empty doc
create empty doc
final documentReference = await FirebaseFirestore.instance.collection('mycoll').add({'id':''});
use doc id to save file obtained from
documentReference.id
makes this redudant
//get firestore doc id
final postid = FirebaseFirestore.instance.collection('properties').doc().id;
on done saving file , save your doc with the id above
FirebaseFirestore.instance.collection('properties').doc(documentReference.id)
.set(servicemodel.toJson());```
You can upload Image and update fields related withthis function. Its work for me.
static String staticImagePath= "";
final FirebaseAuth _auth = FirebaseAuth.instance;
File? file;
Future uploadImageToFirebaseStorage() async {
var _user = _auth.currentUser!.uid;
var _propertiesCollection= FirebaseFirestore.instance
.collection('Properties')
.where('postId', isEqualTo: _user);
var querySnapshots = await _propertiesCollection.get();
try {
var _image = await ImagePicker().pickImage(source: ImageSource.gallery);
file = File(_image!.path);
firebase_storage.Reference _refPath = firebase_storage
.FirebaseStorage.instance
.ref()
.child('MyImageRepo')
.child(_auth.currentUser!.uid);
firebase_storage.UploadTask _uploadTask = _refPath.putFile(file!);
String _url = await (await _uploadTask).ref.getDownloadURL();
staticImagePath = _url.toString();
await _propertiesCollection.doc(_auth.currentUser!.uid).update(({
'postId': staticImagePath,
}));
} catch (e) {
return Center(child: Text(e.toString()));
}
}

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.

Flutter Firebase Storage listAll

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

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