Flutter 异步:Future.wait() 不断返回 null
Flutter Async: Future.wait() constantly returning null
出于某种原因,Future.wait()
一直在 returning null
。我不确定我是否正确使用它。
对于上下文,我在 Firebase 中收集了 posts
。对于每个 post,我可以提取分配给它的 userID
,然后对于每个 post,我分别使用 poster 的 userID
来获取 username
用于显示目的。我从快照中抓取 Post
:
static Future<Post> fromSnapshot(QueryDocumentSnapshot<Object?> doc) async {
final _documentId = doc.id;
final _title = doc.get('title');
final _text = doc.get('text');
final _createdOn = doc.get('createdOn');
final _userID = doc.get('userID');
final userDoc = await FirebaseFirestore.instance.collection('users').doc(_userID).get();
final username = userDoc.get("username");
return Post(documentId: _documentId, title: _title, text: _text, createdOn: _createdOn, username: username);
}
并且 posts
的提取发生在其他地方的 getPosts()
函数中:
Future<List<Post>> getPosts() async {
QuerySnapshot posts = await FirebaseFirestore.instance.collection('posts').get();
final allData = posts.docs.map(
(doc) async => await Post.fromSnapshot(doc)
).toList();
print(allData); // [Instance of 'Future<Post>', Instance of 'Future<Post>', Instance of 'Future<Post>']
final futurePosts = Future.wait(allData);
print(futurePosts); // Instance of 'Future<List<Post>>'
// why does this always return null?
return futurePosts;
}
问题是提取 posts 和获取用户名必须是异步的,这意味着它 returns 是未来 posts 的未来列表。我想将 getPosts()
的结果传递给 FutureBuilder
,所以我需要一个 post 的 Future List
,而不是让所有的 post Future
我使用 Future.wait
- 但似乎总是 return 无效。本质上,我将快照中的每个 post 映射到它自己的 Post
项目,在构造函数中它需要 运行 进一步的 async
调用来提取 username
.我错过了什么吗?
注意:即使制作 Future.wait()
await
returns null
,它也不会 return 成为 List
输入 Future
所以我也不能在 FutureBuilder
中使用它。
编辑 1:
原来futurePosts
其实是一个Instance of 'Future<List<Post>>'
,但是在FutureBuilder内部访问数据时,snapshot.data
是null
:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Feed'),
),
body: FutureBuilder(
future: getPosts(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
print(snapshot.data);
return postsToColumn(context, snapshot.data as List<Post>);
}
return const Center(
child: CircularProgressIndicator(),
);
}
),
);
}
好的,非常感谢@IvoBeckers 帮助我确定了这一点。事实证明,正如他们所说,snapshot
实际上确实有错误,但除非您明确打印,否则不会打印:
if (snapshot.hasError) {
print(snapshot.error.toString());
}
错误是
Bad state: cannot get a field on a DocumentSnapshotPlatform which does not exist
所以事实证明并不是每个 User
在 users
集合中都有一个对应的条目及其 username
,这听起来像是我之前应该检查过的东西,但我认为这样的错误将在控制台中打印出来。一旦我更新了 users
集合,它就完美地工作了。
出于某种原因,Future.wait()
一直在 returning null
。我不确定我是否正确使用它。
对于上下文,我在 Firebase 中收集了 posts
。对于每个 post,我可以提取分配给它的 userID
,然后对于每个 post,我分别使用 poster 的 userID
来获取 username
用于显示目的。我从快照中抓取 Post
:
static Future<Post> fromSnapshot(QueryDocumentSnapshot<Object?> doc) async {
final _documentId = doc.id;
final _title = doc.get('title');
final _text = doc.get('text');
final _createdOn = doc.get('createdOn');
final _userID = doc.get('userID');
final userDoc = await FirebaseFirestore.instance.collection('users').doc(_userID).get();
final username = userDoc.get("username");
return Post(documentId: _documentId, title: _title, text: _text, createdOn: _createdOn, username: username);
}
并且 posts
的提取发生在其他地方的 getPosts()
函数中:
Future<List<Post>> getPosts() async {
QuerySnapshot posts = await FirebaseFirestore.instance.collection('posts').get();
final allData = posts.docs.map(
(doc) async => await Post.fromSnapshot(doc)
).toList();
print(allData); // [Instance of 'Future<Post>', Instance of 'Future<Post>', Instance of 'Future<Post>']
final futurePosts = Future.wait(allData);
print(futurePosts); // Instance of 'Future<List<Post>>'
// why does this always return null?
return futurePosts;
}
问题是提取 posts 和获取用户名必须是异步的,这意味着它 returns 是未来 posts 的未来列表。我想将 getPosts()
的结果传递给 FutureBuilder
,所以我需要一个 post 的 Future List
,而不是让所有的 post Future
我使用 Future.wait
- 但似乎总是 return 无效。本质上,我将快照中的每个 post 映射到它自己的 Post
项目,在构造函数中它需要 运行 进一步的 async
调用来提取 username
.我错过了什么吗?
注意:即使制作 Future.wait()
await
returns null
,它也不会 return 成为 List
输入 Future
所以我也不能在 FutureBuilder
中使用它。
编辑 1:
原来futurePosts
其实是一个Instance of 'Future<List<Post>>'
,但是在FutureBuilder内部访问数据时,snapshot.data
是null
:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Feed'),
),
body: FutureBuilder(
future: getPosts(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
print(snapshot.data);
return postsToColumn(context, snapshot.data as List<Post>);
}
return const Center(
child: CircularProgressIndicator(),
);
}
),
);
}
好的,非常感谢@IvoBeckers 帮助我确定了这一点。事实证明,正如他们所说,snapshot
实际上确实有错误,但除非您明确打印,否则不会打印:
if (snapshot.hasError) {
print(snapshot.error.toString());
}
错误是
Bad state: cannot get a field on a DocumentSnapshotPlatform which does not exist
所以事实证明并不是每个 User
在 users
集合中都有一个对应的条目及其 username
,这听起来像是我之前应该检查过的东西,但我认为这样的错误将在控制台中打印出来。一旦我更新了 users
集合,它就完美地工作了。