You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中Firebase Realtime Database更新数据时新增记录如何修复

问题根因

  • 跳转更新页时传递的id是节点内部存储的id字段值,不是Firebase Realtime Database自动生成的节点唯一key,调用update时用了不存在的key,自然会新增节点
  • 更新提交时用的是路由传入的原始值widget.name、widget.description,没有读取输入框修改后的值,即使更新成功也不会生效
  • TextEditingController放在build方法中定义且在build内调用setState,会触发不必要的页面重建,属于错误写法

修复步骤

  1. 修改_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
  )));
  1. 调整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);
  }
}
  1. 额外确认你的Realtime Database规则允许对对应节点的修改权限,避免权限问题导致更新失败。

内容的提问来源于stack exchange,提问作者walr0s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 15:42:03