Flutter get image from firebase storage and show it in app

2,432

Solution 1

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

Solution 2

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;
}
Share:
2,432
Frank van Puffelen
Author by

Frank van Puffelen

I am an engineer for Firebase at Google. I respond equally well to being called "Frank" or "puf".

Updated on December 07, 2022

Comments

  • Frank van Puffelen
    Frank van Puffelen over 1 year

    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?

  • lejlun
    lejlun over 2 years
    If @Frank saved the day, you should let him know. Rather than posting a duplicate answer you can use the to accept his answer.
  • Admin
    Admin over 2 years
    Thx. For the information. Its my first time (:
  • Admin
    Admin over 2 years
    Thx Frank for your Support, you saved my day (: Now it worked