Abderrezak Douba
Abderrezak Douba

Reputation: 115

_TypeError (type 'Future<dynamic>' is not a subtype of type 'Widget')

am trying to call the user from data (am using firebase as database) the profile page not working for more understanding check the other issue i posted last day : FirebaseException ([cloud_firestore/unavailable] The service is currently unavailable , and how to solve it

import 'package:cached_network_image/cached_network_image.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:yumor/models/progress.dart';
import 'package:yumor/models/user_model.dart';

class profile extends StatefulWidget {
  const profile({Key? key,required this.userProfile}) : super(key: key);
  final String? userProfile;


  

  @override
  State<profile> createState() => _profileState();
}

class _profileState extends State<profile> {
  final userRef = FirebaseFirestore.instance.collection('users');

  buildprofileheader() async{
    final doc=await userRef.doc(widget.userProfile).get();
      if(doc.exists){ 
        var data=doc.data();
      }
    return FutureBuilder(future:FirebaseFirestore.instance.collection('users').doc(userRef.id).get(),
    builder: ((context, snapshot) {
      if(!snapshot.hasData){
        return CircularProgress();
      }
      UserModel user=UserModel.fromMap(Map);
      return Padding(padding:EdgeInsets.all(16.0),
      child: Column(
        children: [
                  Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Icon(Icons.account_circle, size: 90,)
            ],
          ),
          Container(
            alignment: Alignment.center,
            padding: EdgeInsets.all(12.0),
            child: Text(
              user.Username as String,
              style: TextStyle(
                fontWeight: FontWeight.bold,
                fontSize:16.0,
              ),
            ),
          ),
        ],
      ),
      );
    }),
       );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          centerTitle: true,
          title: Text(
            "Profile",
          ),
        ),
        body: ListView(children: <Widget>[
           buildprofileheader(), // the error shows in this line <=======
        ]));
  }
}

Upvotes: 0

Views: 56

Answers (2)

Md. Yeasin Sheikh
Md. Yeasin Sheikh

Reputation: 63594

As for the logic part, you can simplify the logic for future method something like

  Future<UserModel?> getData() async {
  try{
    final userRef = FirebaseFirestore.instance.collection('users');
    final doc = await userRef.doc(widget.userProfile).get();
    if (doc.exists) {
      var data = doc.data(); // not sure about this use case
    } else {
      return null;
    }

    final data = await FirebaseFirestore.instance
        .collection('users')
        .doc(userRef.id)
        .get();

    if (data.exists) {
      UserModel user = UserModel.fromMap(data);
      return user;
    }
  } catch(e){ }
 
  }

Create a state variable for future method , and use like

late final future = getData(); 

Widget buildprofileheader() {
    return FutureBuilder<UserModel?>(
      future: future,
      builder: ((context, snapshot) {
        if (!snapshot.hasData) {
          return CircularProgress();
        }
        return Padding(....
class _profileState extends State<profile> {

  Future<UserModel?> getData() async {
    final userRef = FirebaseFirestore.instance.collection('users');
    final doc = await userRef.doc(widget.userProfile).get();
    if (doc.exists) {
      var data = doc.data(); // not sure about this use case
    } else {
      return null;
    }

    final data = await FirebaseFirestore.instance
        .collection('users')
        .doc(userRef.id)
        .get();

    if (data.exists) {
      UserModel user = UserModel.fromMap(data);
      return user;
    }
  }

  late final future = getData();

  Widget buildprofileheader() {
    return FutureBuilder<UserModel?>(
      future: future,
      builder: ((context, snapshot) {
        if (!snapshot.hasData) {
          return CircularProgressIndicator();
        }
        return Padding(
          padding: EdgeInsets.all(16.0),
          child: Column(
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Icon(
                    Icons.account_circle,
                    size: 90,
                  )
                ],
              ),
              Container(
                alignment: Alignment.center,
                padding: EdgeInsets.all(12.0),
                child: Text(
                  user.Username as String,
                  style: TextStyle(
                    fontWeight: FontWeight.bold,
                    fontSize: 16.0,
                  ),
                ),
              ),
            ],
          ),
        );
      }),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          centerTitle: true,
          title: Text(
            "Profile",
          ),
        ),
        body: ListView(children: <Widget>[
          buildprofileheader(),
        ]));
  }
}

Upvotes: 1

eamirho3ein
eamirho3ein

Reputation: 17890

Your buildprofileheader return type is Future<Widget> but it should be Widget in order to use in ListView, so you need to use an other FutureBuilder to get userRef. So just wrap your current FutureBuilder with an other one.

Upvotes: 1

Related Questions