Future builder 没有获取数据
Future builder is not getting data
我在我的代码中使用 FutureBuilder
来查询 Firestore
,但我一直没有从我在 FutureBuilder
中指定的函数中获取任何数据。但有趣的是,函数正在执行并获取数据。它只是没有将它传递给 FutureBuilder
.
代码:
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:garuda_academy_app/Tools/FixedColors.dart';
class CoursePage extends StatefulWidget {
CoursePage({this.userEmail});
final String userEmail;
@override
_CoursePageState createState() => _CoursePageState();
}
class _CoursePageState extends State<CoursePage> {
@override
void initState() {
super.initState();
}
Future<List<DocumentSnapshot>> _getCourses() async {
List<DocumentSnapshot> userCourses = [];
await Firestore.instance
.collection("Users")
.document(widget.userEmail)
.get()
.then((DocumentSnapshot userDetails) {
List<dynamic> courses = userDetails["Courses"];
courses.forEach((dynamic course) {
Firestore.instance
.collection("Courses")
.document(course)
.get()
.then((DocumentSnapshot courseDetails) {
userCourses.add(courseDetails);
print(userCourses.length);
});
});
});
return userCourses;
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: secondaryColor,
resizeToAvoidBottomInset: false,
body: FutureBuilder(
future: _getCourses(),
builder: (context, AsyncSnapshot<List<DocumentSnapshot>> snapshot) {
// loading display
if (snapshot.hasError ||
(snapshot.connectionState == ConnectionState.waiting)) {
if (snapshot.hasError) print('${snapshot.error}');
return Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(primaryColor),
),
);
}
print(snapshot.data.length);
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return Text(
snapshot.data[index].documentID,
style: TextStyle(color: Colors.black),
);
},
);
},
),
);
}
}
注意我打印了两次数据长度来检查我是否得到任何东西,输出是这样的:
0 // the future print
1 // the function print
似乎 await
没有发挥应有的作用,因为未来似乎在 await
之前采用 List
。
有谁知道为什么会这样?
问题是您在 FutureBuilder Widget 内部调用异步方法。在 initState 方法中调用该函数并在一个变量中获取 return 值并在 FutureBuilder Widget 中使用它。
Check this link for more understanding
Future<List<DocumentSnapshot>> _course;
void initState()
{
super.initState();
course= _getCourses()
}
在 FutureBuilder Widget 中使用课程变量
FutureBuilder(
future: _course,
builder: write your code)
需要从 StreamBuilder 而非 FutureBuilder 调用 Firestore 实例,您可以从 Flutter 文档中查看有关此小部件的 this 页面。
这是团队的例子:
StreamBuilder<int>(
stream: _lot?.bids, // a Stream<int> or null
builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
if (snapshot.hasError)
return Text('Error: ${snapshot.error}');
switch (snapshot.connectionState) {
case ConnectionState.none: return Text('Select lot');
case ConnectionState.waiting: return Text('Awaiting bids...');
case ConnectionState.active: return Text('$${snapshot.data}');
case ConnectionState.done: return Text('$${snapshot.data} (closed)');
}
return null; // unreachable
},
)
我在我的代码中使用 FutureBuilder
来查询 Firestore
,但我一直没有从我在 FutureBuilder
中指定的函数中获取任何数据。但有趣的是,函数正在执行并获取数据。它只是没有将它传递给 FutureBuilder
.
代码:
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:garuda_academy_app/Tools/FixedColors.dart';
class CoursePage extends StatefulWidget {
CoursePage({this.userEmail});
final String userEmail;
@override
_CoursePageState createState() => _CoursePageState();
}
class _CoursePageState extends State<CoursePage> {
@override
void initState() {
super.initState();
}
Future<List<DocumentSnapshot>> _getCourses() async {
List<DocumentSnapshot> userCourses = [];
await Firestore.instance
.collection("Users")
.document(widget.userEmail)
.get()
.then((DocumentSnapshot userDetails) {
List<dynamic> courses = userDetails["Courses"];
courses.forEach((dynamic course) {
Firestore.instance
.collection("Courses")
.document(course)
.get()
.then((DocumentSnapshot courseDetails) {
userCourses.add(courseDetails);
print(userCourses.length);
});
});
});
return userCourses;
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: secondaryColor,
resizeToAvoidBottomInset: false,
body: FutureBuilder(
future: _getCourses(),
builder: (context, AsyncSnapshot<List<DocumentSnapshot>> snapshot) {
// loading display
if (snapshot.hasError ||
(snapshot.connectionState == ConnectionState.waiting)) {
if (snapshot.hasError) print('${snapshot.error}');
return Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(primaryColor),
),
);
}
print(snapshot.data.length);
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return Text(
snapshot.data[index].documentID,
style: TextStyle(color: Colors.black),
);
},
);
},
),
);
}
}
注意我打印了两次数据长度来检查我是否得到任何东西,输出是这样的:
0 // the future print
1 // the function print
似乎 await
没有发挥应有的作用,因为未来似乎在 await
之前采用 List
。
有谁知道为什么会这样?
问题是您在 FutureBuilder Widget 内部调用异步方法。在 initState 方法中调用该函数并在一个变量中获取 return 值并在 FutureBuilder Widget 中使用它。
Check this link for more understanding
Future<List<DocumentSnapshot>> _course;
void initState()
{
super.initState();
course= _getCourses()
}
在 FutureBuilder Widget 中使用课程变量
FutureBuilder(
future: _course,
builder: write your code)
需要从 StreamBuilder 而非 FutureBuilder 调用 Firestore 实例,您可以从 Flutter 文档中查看有关此小部件的 this 页面。
这是团队的例子:
StreamBuilder<int>(
stream: _lot?.bids, // a Stream<int> or null
builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
if (snapshot.hasError)
return Text('Error: ${snapshot.error}');
switch (snapshot.connectionState) {
case ConnectionState.none: return Text('Select lot');
case ConnectionState.waiting: return Text('Awaiting bids...');
case ConnectionState.active: return Text('$${snapshot.data}');
case ConnectionState.done: return Text('$${snapshot.data} (closed)');
}
return null; // unreachable
},
)