firebase - Flutter Streambuilder 流不一致的 FirebaseFirestore 快照数据
问题描述
检索购物车项目我的快照数据不一致。当购物车中有一件商品时,我会得到格式正确的结果:
{1111111111111: 1, PriceSmart: 540.0}
当购物车中有两个项目,第二个项目也是“PriceSmart”时,我得到一个错误,因为返回这个结果:
{1111111111111: 1, PriceSmart: 300.0, 5555555555555: 1}
应该是:
{1111111111111: 1, PriceSmart: 540.0, 5555555555555: 1, PriceSmart: 300.0}
这是我的 Firebase 数据结构:
第一个购物车项目:
第二个购物车项目:
基本上是结合“卖家”(PriceSmart),当我需要从每个购物车项目返回完整数据时,否则一旦我在购物车中有多个项目并且卖家是相同的,我就会收到错误。
请检查我的代码中的流,看看这个实现有什么问题:
class PriceUpdaterWidget extends StatefulWidget {
const PriceUpdaterWidget({
Key? key,
required this.loginService,
required this.code,
required this.itemSubCategory,
}) : super(key: key);
final LoginService loginService;
final String? code;
final SubCategory? itemSubCategory;
_PriceUpdaterWidgetState createState() => _PriceUpdaterWidgetState();
}
class _PriceUpdaterWidgetState extends State<PriceUpdaterWidget> {
@override
Widget build(BuildContext context) {
CategorySelectionService catSelection =
Provider.of<CategorySelectionService>(context, listen: false);
Stream<DocumentSnapshot> priceDocStream = FirebaseFirestore.instance
.collection('shoppers')
.doc(widget.loginService.loggedInUserModel!.uid)
.collection("cartItems")
.doc(widget.code)
.snapshots();
return StreamBuilder<DocumentSnapshot>(
stream: priceDocStream,
builder:
(BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
SellerNameService isSellerName =
Provider.of<SellerNameService>(context, listen: false);
var sellerName = isSellerName.isSellerName;
if (snapshot.data != null) {
return Text(
snapshot.data![sellerName].toStringAsFixed(2),
textAlign: TextAlign.center,
);
} else {
return Text('No Data');
}
});
}
}
解决方案
如果没有看到更多代码,很难创建一个完全符合您的规范的示例,并且您得到的错误与您发布的代码不匹配,但是,从广义上讲,您需要:
- 将您的功能移到
Stream
外部build
initState
- 一次处理每个快照
- 远离处理构建小部件中的数据
class PriceUpdaterWidget extends StatefulWidget {
final String login, code;
const PriceUpdaterWidget(this.login, this.code);
@override
_PriceUpdaterWidgetState createState() => _PriceUpdaterWidgetState ();
}
class _PriceUpdaterWidgetState extends State<PriceUpdaterWidget> {
Stream<DocumentSnapshot> priceStream; // only one stream per widget
@override
void initState() {
super.initState();
priceStream = FirebaseFirestore.instance // set the stream once
.collection("shoppers")
.doc(widget.login)
.collection("cartItems")
.doc(widget.code)
.snapshots();
}
@override
Widget build(BuildContext context) => StreamBuilder<DocumentSnapshot>(
stream: priceStream,
builder: (context, snapshot) {
const String sellerName = "PriceSmart";
return snapshot.data == null
? const Text("No data")
: Text(
snapshot.data[sellerName].toStringAsFixed(2),
textAlign: TextAlign.center,
);
}
);
}
推荐阅读
- c++ - 重载 C++ 运算符以将对象中的指针设置为其他对象
- python - 如何在 for 循环中使用 p 值计算 Kendall Tau 和 Pearson corr coeff 时两个值都为 0 时排除?
- java - 使用不带字段映射的隐藏列对 @OneToMany 关系进行 JPA2 条件查询
- sql - 每天计数 DB2
- php - PHP - 执行 SQL 调用函数不起作用
- ios - 列表内的多行文本视图/具有动态单元格高度的 ForEach SWIFTUI
- c# - 在 C# 中迭代 Json
- r - 如何使用 R 在足球数据库中拆分字符串值
- python - 为什么一个数字,例如 2 % 一个大于零的空集是真的?
- node.js - 摩卡抱怨与木偶表演者超时