Flutter中Firebase Realtime Database更新数据时新增记录如何修复
问题根因
- 跳转更新页时传递的
id是节点内部存储的id字段值,不是Firebase Realtime Database自动生成的节点唯一key,调用update时用了不存在的key,自然会新增节点 - 更新提交时用的是路由传入的原始值
widget.name、widget.description,没有读取输入框修改后的值,即使更新成功也不会生效 TextEditingController放在build方法中定义且在build内调用setState,会触发不必要的页面重建,属于错误写法
修复步骤
- 修改
_UpdateDestinationsState中跳转传参逻辑,将snapshot.key作为id传递,替换原来的snapshot.value['id']
Navigator.of(context).push(MaterialPageRoute( builder: (context) => UpdatePage( name: snapshot.value['name'], description: snapshot.value['description'], id: snapshot.key!, // 改用节点的唯一key )));
- 调整
UpdatePage的代码,将控制器定义为State类属性,在initState中初始化赋值,提交更新时读取控制器的最新值
class _UpdatePageState extends State<UpdatePage> { final destdatabaseref = FirebaseDatabase.instance .reference() .child('Database') .child('DestinationsandActivities'); // 控制器定义为State的属性 late final TextEditingController nameController; late final TextEditingController descriptionController; @override void initState() { super.initState(); // 初始化放在initState中执行 nameController = TextEditingController(text: widget.name); descriptionController = TextEditingController(text: widget.description); } @override void dispose() { // 页面销毁时释放控制器 nameController.dispose(); descriptionController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( iconTheme: IconThemeData(color: Colors.white), backgroundColor: Color(0xFF3d5a89), elevation: 0, centerTitle: true, title: const Text('Update Destinations', style: TextStyle( fontSize: 18, fontWeight: FontWeight.w500, color: Colors.white)), ), body: Form( child: Padding( padding: EdgeInsets.all(8), child: Column( children: [ TextFormField( controller: nameController, autofocus: false, decoration: InputDecoration( labelText: 'Name', border: OutlineInputBorder(), ), ), SizedBox(height: 10), TextFormField( controller: descriptionController, autofocus: false, decoration: InputDecoration( labelText: 'Description', border: OutlineInputBorder(), ), ), TextButton( onPressed: () { // 读取输入框的最新值提交 updateData(nameController.text, descriptionController.text, widget.id); Navigator.pop(context); }, child: Text('Update')), TextButton( onPressed: () { Navigator.of(context).pop(); }, child: Text('Cancel')), ], ), ), )); } void updateData(String name, String description, var key) { Map<String, String> newvalue = {'name': name, 'description': description}; destdatabaseref.child(key).update(newvalue); } }
- 额外确认你的Realtime Database规则允许对对应节点的修改权限,避免权限问题导致更新失败。
内容的提问来源于stack exchange,提问作者walr0s
相关产品推荐
相关产品推荐

