[英]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?我对 flutter 有点陌生,我一直在构建一个使用 firebase 作为后端的小应用程序,每当我尝试从 firebase 加载数据时,我都无法获取值,直到我重新加载应用程序,这不是整个代码,我认为小部件在数据本身之前加载,真的可以使用你的帮助,有什么方法可以使用状态来刷新值?
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,),
),
);
}
}
Yo need to setState() in getUser() and also check if snapshot has data or not also.so the modified code will be你需要在 getUser() 中 setState() 并检查快照是否有数据。所以修改后的代码将是
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,),
),
);
}
}
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.小部件在调用initState
后立即initState
但您使用Future
获取用户数据,因此Future
可能尚未完成。 So you just need to wrap your main widget with FutureBuilder :所以你只需要用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()
],
),
),
),
},
);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.