Reputation:
im trying to get an Image from my firebase storage and add it in my Code.
My Code:
loadImage() async{
//current user id
final _userID = FirebaseAuth.instance.currentUser!.uid;
//collect the image name
DocumentSnapshot variable = await FirebaseFirestore.instance.
collection('data_user').
doc('user').
collection('personal_data').
doc(_userID).
get();
//a list of images names (i need only one)
var _file_name = variable['path_profile_image'];
//select the image url
Reference ref = FirebaseStorage.instance.ref().child("images/user/profile_images/${_userID}").child(_file_name[0]);
//get image url from firebase storage
var url = await ref.getDownloadURL();
//logging
print('Image Url: ' + url.toString());
//return image.network
return Image.network(url.toString());
}
I have create for each user a document. In the document i save the image name. See data base:
To get the profile picture i take the image name and go to firebase storage. Then i take the image which has the same image name as the image in firebase database.
Firebase storage:
How i can take an image from firebase storage and show it in my app?
Upvotes: 2
Views: 8565
Reputation:
Thx @Frank. Im got it. You saved my Day (:
My solution:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
class DebugPage extends StatefulWidget {
@override
_DebugPage createState() => _DebugPage();
}
class _DebugPage extends State<DebugPage> {
@override
Widget build(BuildContext context) {
return
new FutureBuilder <String>(
future: loadImage(),
builder: (BuildContext context, AsyncSnapshot<String> image) {
if (image.hasData) {
return Image.network(image.data.toString()); // image is ready
//return Text('data');
} else {
return new Container(); // placeholder
}
},
);
}
}
Future <String> loadImage() async{
//current user id
final _userID = FirebaseAuth.instance.currentUser!.uid;
//collect the image name
DocumentSnapshot variable = await FirebaseFirestore.instance.
collection('data_user').
doc('user').
collection('personal_data').
doc(_userID).
get();
//a list of images names (i need only one)
var _file_name = variable['path_profile_image'];
//select the image url
Reference ref = FirebaseStorage.instance.ref().child("images/user/profile_images/${_userID}").child(_file_name[0]);
//get image url from firebase storage
var url = await ref.getDownloadURL();
print('url: ' + url);
return url;
}
Upvotes: 1
Reputation: 600006
It seems that you're calling loadImage
from within your build
method, which won't work because you can't asynchronously load widgets.
What you can do however is load data asynchronously, and then store that in the state. When you update the state, Flutter rerenders the UI, so that it always reflects the new state.
So the solution is to store the download URL in the state, and then load it from there.
loadImage() async{
//current user id
final _userID = FirebaseAuth.instance.currentUser!.uid;
//collect the image name
DocumentSnapshot variable = await FirebaseFirestore.instance.
collection('data_user').
doc('user').
collection('personal_data').
doc(_userID).
get();
//a list of images names (i need only one)
var _file_name = variable['path_profile_image'];
//select the image url
Reference ref = FirebaseStorage.instance.ref().child("images/user/profile_images/${_userID}").child(_file_name[0]);
//get image url from firebase storage
var url = await ref.getDownloadURL();
// put the URL in the state, so that the UI gets rerendered
setState(() {
url: url
})
}
And then you can use the url
from the state in the build
method:
Image.network(url.toString());
Now the only thing left to do is call loadImage
once, typically when the stateful widget that it is in is first initialized.
Alternatively, you can use a FutureBuilder
in your build method to wrap the Image.network
widget, and then use an approach similar to this to get the download URL in there: How to initialize a class with async
Upvotes: 3