Flutter Firebase ListView绑定Firestore数据时如何在onPressed中更新指定属性
实现方案
核心逻辑
你可以通过遍历拿到的文档对象的id属性定位到目标文档,直接调用Firestore提供的更新接口即可,修改后的代码示例如下:
StreamBuilder<QuerySnapshot>( stream: db.collection('encheres').snapshots(), builder: (context, AsyncSnapshot snapshot) { if (!snapshot.hasData) { return const Center( child: CircularProgressIndicator(), ); } else { return Expanded( child: ListView( scrollDirection: Axis.vertical, shrinkWrap: true, children: snapshot.data!.docs.map<Widget>( (doc) { // 拿到当前文档的id,用于后续更新定位 String documentId = doc.id; // 也可以先拿到当前文档的字段值 Map<String, dynamic> data = doc.data() as Map<String, dynamic>; return Card( // 点击事件也可以绑定在Card内部的按钮的onPressed属性中 child: InkWell( onTap: () async { try { // 调用update方法更新指定字段,示例为修改price和is_actived字段 await db.collection('encheres').doc(documentId).update({ "price": data['price'] + 10, "is_actived": false // 可自行补充其他需要更新的字段键值对 }); // 可选:更新成功后给用户提示 if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("更新成功")) ); } } catch (e) { // 可选:捕获更新失败的异常做处理 if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text("更新失败:$e")) ); } } }, // 此处保留你原来的Card内部布局代码 child: Padding( padding: const EdgeInsets.all(16), child: Text(data['title'] ?? '无标题'), ), ) ); }, ).toList(), ), ); } }, )
注意事项
- 如果你需要覆盖整个文档的内容,而不是仅修改指定字段,可以把
update方法替换为set方法 - 你配置的Firebase数据库权限需要开启对应集合的写权限,否则更新会触发权限拒绝异常
- 因为你用了StreamBuilder监听集合变化,更新成功后列表会自动刷新,不需要手动调用setState
内容的提问来源于stack exchange,提问作者Wassef Hassine
相关产品推荐
相关产品推荐

