我正在尝试从 Firestore 数据库中获取 brews 集合中的文档。
我编写了如下代码,但它的数组为空。
我的代码有什么问题?
帮助我一个习惯了颤抖和火力的人。
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:brew_crew/models/brew.dart';
class DatabaseService {
final String uid;
DatabaseService({ this.uid });
// collection references
final CollectionReference brewCollection = FirebaseFirestore.instance.collection("brews");
~~~ short cut ~~~
// brew list from snapshot
List<Brew> _brewListFromSnapshot(QuerySnapshot snapshot) {
print(snapshot.docs.length); // return 0.
// print(snapshot.docs.toString()); // here this returns [].
return snapshot.docs.map((doc) {
return Brew(
name: doc.data()['name'] ?? '',
strength: doc.data()['strength'] ?? 0,
sugars: doc.data()['sugars'] ?? 0,
);
}).toList();
}
Stream<List<Brew>> get brews {
return brewCollection.snapshots()
.map(_brewListFromSnapshot);
}
}
使用流添加代码
home.dart
import 'package:brew_crew/screens/services/auth.dart';
import 'package:brew_crew/screens/services/database.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:brew_crew/screens/home/brew_list.dart';
class Home extends StatelessWidget {
final AuthService _auth = AuthService();
@override
Widget build(BuildContext context) {
return StreamProvider<List<Brew>>.value(
value: DatabaseService().brews, // here using the stream.
child: Scaffold(
~~~ short cut ~~~
body: BrewList(), // here too.
),
);
}
}
这是一个用于主屏幕页面的文件,使 DatabaseService 实例调用 brews 流。
这是将 brews 流作为值传递给 Provider,该值在 body 中的 BrewList 实例中调用。
brew_list.dart
import 'package:brew_crew/models/brew.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class BrewList extends StatefulWidget {
@override
_BrewListState createState() => _BrewListState();
}
class _BrewListState extends State<BrewList> {
@override
Widget build(BuildContext context) {
final brews = Provider.of<List<Brew>>(context);
brews.forEach((brew) {
print(brew.name);
print(brew.sugars);
});
// print(brews.toString()); // here returns [] too.
return Container();
}
}
在 BrewList 类中,只调用 Provider 值。
已添加
brew_list.dart
print(brews.length);
返回
Performing hot reload...
Syncing files to device iPhone 8...
flutter: 0
Reloaded 4 of 667 libraries in 253ms.
flutter: 0
flutter: 0
已添加
在 brew_list.dart 中使用 forEach 时出现此错误。
The following NoSuchMethodError was thrown building BrewList(dirty, dependencies: [_InheritedProviderScope<List<Brew>>], state: _BrewListState#eaba8):
The method 'forEach' was called on null.
Receiver: null
Tried calling: forEach(Closure: (Brew) => Null)
答案 0 :(得分:0)
您的 Print 正在尝试将对象数组转换为无效或 Stringable 的字符串,因为它也包含循环引用。
但是,snapshot.docs
是可迭代的,使用 forEach 将根据您的需要处理每个文档。
只需确保在处理快照之前完成快照,方法是根据需要在您的 Stream Provider 中等待或处理它。
您可以使用 snapshot.docs.length
检查文档的数量,如果您看到返回值,则必须进一步调试。
答案 1 :(得分:0)
您收到该错误是因为您正在尝试输出尚未完全提取的数据。您的流正在从 Firestore 获取数据,但需要时间将其全部发送出去。因此,我建议使用像 ?? 这样的空感知运算符,或者只是检查自己是否为空,如果不是,则同时显示不同的小部件。
final brews = Provider.of<List<Brew>>(context);
return brews == null ? CircularProgressIndicator() :
ListView.builder(
itemCount: brews.length,
itemBuilder: (context, index) {
return Text("${brews[index].name}");
},
);
答案 2 :(得分:0)
抱歉,我注意到我弄错了集合名称。 不是“酿造”而是“酿造”。
非常感谢您帮助我。