Flutter 从 firebase 存储中获取图像并在应用程序中显示

Flutter get image from firebase storage and show it in app

我正在尝试从我的 firebase 存储中获取图像并将其添加到我的代码中。

我的代码:

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

我已经为每个用户创建了一个文档。 在文档中我保存图像名称。 查看数据库:

为了获取个人资料图片,我使用图片名称 然后去 Firebase 存储。 然后我拍摄与 firebase 数据库中的图像具有相同图像名称的图像。

Firebase 存储:

如何从 firebase 存储中获取图像并将其显示在我的应用程序中?

您似乎是从 build 方法中调用 loadImage,该方法不起作用,因为您无法异步加载小部件。

然而,您可以做的是异步加载数据,然后将其存储在状态中。当您更新状态时,Flutter 会重新渲染 UI,以便它始终反映新状态。

所以解决办法是把下载的URL存入状态,然后从那里加载。

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

然后你可以在build方法中使用来自状态的url

Image.network(url.toString());

现在唯一要做的就是调用 loadImage 一次,通常是在首次初始化它所在的有状态小部件时。


或者,您可以在构建方法中使用 FutureBuilder 来包装 Image.network 小部件,然后使用类似于此的方法在其中获取下载 URL:

谢谢@Frank。 我明白了。 你拯救了我的一天 (:

我的解决方案:

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