Chandru
Chandru

Reputation: 527

Value is retrieved only after hot reload in flutter

I'm kinda new to flutter, I've been building a small app using firebase as the backend, whenever I try to load data from firebase I'm not able to fetch the value until I reload the app, this isn't the entire code, I think the widgets are loading before the data itself, could really use ur help, is there any way that I could use the state to refresh the value?

mycode:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import "package:flutter/material.dart";
import 'package:mine_app/textingpage.dart';

class FriendsPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _FriendsPage();
  }
}

class Friends {
  final int theirTexts;
  final String username;
  final int  myTexts;
  final int totalTexts;
  final String friendId;

  Friends(this.theirTexts,this.totalTexts,this.username,this.myTexts,this.friendId);

  Friends.fromMap(DocumentSnapshot map)
    :assert(map["username"]!=null),
    assert(map["myTexts"]!=null),
    assert(map["theirTexts"]!=null),
    assert(map["totalTexts"]!=null),
    assert(map["uid"]!=null),
    username = map["username"],
    myTexts = map["myTexts"],
    theirTexts = map["theirTexts"],
    totalTexts = map["totalTexts"],
    friendId = map["uid"];
}


class _FriendsPage extends State<FriendsPage> {
  String user;
  String globalid = "";

  Future<void> getuser() async {
    user = (await FirebaseAuth.instance.currentUser()).uid;
  }

  @override
  void initState() {
    getuser();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 2,
      child: Scaffold(
          appBar: AppBar(
            backgroundColor: Color(0xff723881),
            centerTitle: true,
            title: Text(
              "Chats",
            bottom: TabBar(
              tabs: [
                Tab(icon: Icon(Icons.people), text: "People"),
                Tab(icon: Icon(Icons.search), text: "Find"),
              ],
              indicatorColor: Colors.white,
            ),
          ),
          body: TabBarView(
            children: <Widget>[
              Container(
                child: snapShotBuilder(context)
              ),
              Container()
            ],
          )),
    );
  }

  Widget snapShotBuilder(BuildContext context){
    return StreamBuilder<QuerySnapshot>(
      stream: Firestore.instance.collection("users").document(user).collection("friends").snapshots(),
      builder:(context,snapshot){
        if (!snapshot.hasData) {
          return LinearProgressIndicator();
        }
          return myListView(context,snapshot.data.documents); 
    } );
  }

  Widget myListView(BuildContext context,List<DocumentSnapshot> snapshot){
    return Container(
      child: ListView(
        children: snapshot.map((data)=>myfriends(Friends.fromMap(data))).toList(),
      ),
    );
  }

  Widget myfriends(Friends friend) {
    return Container(
      margin: EdgeInsets.only(top: 10.0),
      padding: EdgeInsets.all(5.0),
      child: ListTile(
        onTap:(){
          setState(() {
            globalid = friend.friendId;
          });
          print(friend.friendId);
          Navigator.push(context, MaterialPageRoute(builder: (context)=>ChatPage(userid:friend.friendId)));
        },
        trailing: Container(
            // margin: EdgeInsets.only(top:30.0,left:10.0,right:0.0),
            child: Text(
          friend.totalTexts.toString(),),
        leading: Container(
          width: 60.0,
          height: 60.0,
        ),
        title: Text(friend.username,),
      ),
    );
  }
}

Upvotes: 2

Views: 3735

Answers (2)

BambinoUA
BambinoUA

Reputation: 7100

You are right. Widget is built at once after call of initState but you getting user data using Future so it is possilbe that Future is not completed yet. So you just need to wrap your main widget with FutureBuilder:

@override
Widget build(BuildContext context) {
  return FutureBuilder<String>(
    future: getUser(), // <-- your future
    builder: (context,snapshot) {
      return DefaultTabController(
        length: 2,
        child: Scaffold(
          appBar: AppBar(
            backgroundColor: Color(0xff723881),
            centerTitle: true,
            title: Text(
              "Chats",
            bottom: TabBar(
              tabs: [
                Tab(icon: Icon(Icons.people), text: "People"),
                Tab(icon: Icon(Icons.search), text: "Find"),
              ],
              indicatorColor: Colors.white,
            ),
          ),
          body: TabBarView(
            children: <Widget>[
              Container(
                child: snapShotBuilder(context)
              ),
              Container()
            ],
          ),
        ),
      ),
    },
  );
}

Upvotes: 1

Khadga shrestha
Khadga shrestha

Reputation: 1180

Yo need to setState() in getUser() and also check if snapshot has data or not also.so the modified code will be

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import "package:flutter/material.dart";
import 'package:mine_app/textingpage.dart';

class FriendsPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _FriendsPage();
  }
}

class Friends {
  final int theirTexts;
  final String username;
  final int  myTexts;
  final int totalTexts;
  final String friendId;

  Friends(this.theirTexts,this.totalTexts,this.username,this.myTexts,this.friendId);

  Friends.fromMap(DocumentSnapshot map)
    :assert(map["username"]!=null),
    assert(map["myTexts"]!=null),
    assert(map["theirTexts"]!=null),
    assert(map["totalTexts"]!=null),
    assert(map["uid"]!=null),
    username = map["username"],
    myTexts = map["myTexts"],
    theirTexts = map["theirTexts"],
    totalTexts = map["totalTexts"],
    friendId = map["uid"];
}


class _FriendsPage extends State<FriendsPage> {
  String user;
  String globalid = "";

  Future<void> getuser() async{
    setState((){
       user = (await FirebaseAuth.instance.currentUser()).uid;
    });
  }

  @override
  void initState() {
    getuser();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 2,
      child: Scaffold(
          appBar: AppBar(
            backgroundColor: Color(0xff723881),
            centerTitle: true,
            title: Text(
              "Chats",
            bottom: TabBar(
              tabs: [
                Tab(icon: Icon(Icons.people), text: "People"),
                Tab(icon: Icon(Icons.search), text: "Find"),
              ],
              indicatorColor: Colors.white,
            ),
          ),
          body: TabBarView(
            children: <Widget>[
              Container(
                child: snapShotBuilder(context)
              ),
              Container()
            ],
          )),
    );
  }

  Widget snapShotBuilder(BuildContext context){
    return StreamBuilder<QuerySnapshot>(
      stream: Firestore.instance.collection("users").document(user).collection("friends").snapshots(),
      builder:(context,snapshot){
        if (snapshot.hasData) {
          return myListView(context,snapshot.data.documents); 
        }else if(snapshot.hasError){
          return Center(
          child:Text(snapshot.error.toString()));
        }else{
          return LinearProgressIndicator();
        }

    } );
  }

  Widget myListView(BuildContext context,List<DocumentSnapshot> snapshot){
    return Container(
      child: ListView(
        children: snapshot.map((data)=>myfriends(Friends.fromMap(data))).toList(),
      ),
    );
  }

  Widget myfriends(Friends friend) {
    return Container(
      margin: EdgeInsets.only(top: 10.0),
      padding: EdgeInsets.all(5.0),
      child: ListTile(
        onTap:(){
          setState(() {
            globalid = friend.friendId;
          });
          print(friend.friendId);
          Navigator.push(context, MaterialPageRoute(builder: (context)=>ChatPage(userid:friend.friendId)));
        },
        trailing: Container(
            // margin: EdgeInsets.only(top:30.0,left:10.0,right:0.0),
            child: Text(
          friend.totalTexts.toString(),),
        leading: Container(
          width: 60.0,
          height: 60.0,
        ),
        title: Text(friend.username,),
      ),
    );
  }
}

Upvotes: 2

Related Questions