Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Firebase 如何将Flatter文本字段与Firestore字段同步?_Firebase_Flutter_Google Cloud Firestore - Fatal编程技术网

Firebase 如何将Flatter文本字段与Firestore字段同步?

Firebase 如何将Flatter文本字段与Firestore字段同步?,firebase,flutter,google-cloud-firestore,Firebase,Flutter,Google Cloud Firestore,我在Firestore中有task文档,它在FlatterUI中有todo字段和TextField 请建议如何使textfield与todo字段同步,即 任何时候,textfield中的文本都会随着用户的键入而更改,请使用刚刚键入的值更新todo字段 任何时候,todo字段都会更新(在Firestore控制台中手动或由其他用户进行),使用最新值更新textfield 谢谢 TextField onChanged更新firebase中的值 侦听firebase中的值更改,并使用TextEditin

我在Firestore中有
task
文档,它在FlatterUI中有
todo
字段和
TextField

请建议如何使
textfield
todo
字段同步,即

  • 任何时候,
    textfield
    中的文本都会随着用户的键入而更改,请使用刚刚键入的值更新
    todo
    字段
  • 任何时候,
    todo
    字段都会更新(在Firestore控制台中手动或由其他用户进行),使用最新值更新
    textfield
  • 谢谢

  • TextField onChanged更新firebase中的值
  • 侦听firebase中的值更改,并使用TextEditingController更新TextField的值
  • 代码如下:

    import 'dart:async';
    import 'package:firebase_database/firebase_database.dart';
    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'TODO Screen',
          theme: ThemeData(
            primarySwatch: Colors.orange,
          ),
          home: TODOScreen(),
        );
      }
    }
    
    class TODOScreen extends StatefulWidget {
      @override
      _TODOScreenState createState() => _TODOScreenState();
    }
    
    class _TODOScreenState extends State<TODOScreen> {
      final _ref = FirebaseDatabase.instance.reference().child('todo_id').child('value');
      TextEditingController _todoController = new TextEditingController();
    
      StreamSubscription _subscription;
    
      @override
      void initState() {
        super.initState();
        _subscription = _ref.onValue.listen((data) {
          String value = data.snapshot.value as String ?? "";
          updateOnChanged(value);
        });
      }
    
      saveOnChanged(String value) async {
        await _ref.set(value);
      }
    
      updateOnChanged(String value) async {
        setState(() {
          _todoController.value = _todoController.value.copyWith(
            text: value,
          );
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('TODO Screen'),
          ),
          body: Center(
            child: Container(
              padding: EdgeInsets.all(10.0),
              child: TextField(
                decoration: InputDecoration(labelText: "TODO"),
                maxLines: 5,
                onChanged: saveOnChanged,
                controller: _todoController,
              ),
            ),
          ),
        );
      }
    
      @override
      void dispose() {
        _todoController.dispose();
    
        if (_subscription != null) _subscription.cancel();
    
        super.dispose();
      }
    }
    
    导入'dart:async';
    导入“package:firebase_database/firebase_database.dart”;
    进口“包装:颤振/材料.省道”;
    void main()=>runApp(MyApp());
    类MyApp扩展了无状态小部件{
    @凌驾
    小部件构建(构建上下文){
    返回材料PP(
    标题:“待办事项屏幕”,
    主题:主题数据(
    原始样本:颜色。橙色,
    ),
    主页:TODOScreen(),
    );
    }
    }
    类TODOScreen扩展了StatefulWidget{
    @凌驾
    _TODOScreenState createState()=>\u TODOScreenState();
    }
    类_TODOScreenState扩展了状态{
    final _ref=FirebaseDatabase.instance.reference().child('todo_id').child('value');
    TextEditingController_todoController=新的TextEditingController();
    流动认购(流动认购);;
    @凌驾
    void initState(){
    super.initState();
    _订阅=_ref.onValue.listen((数据){
    字符串值=data.snapshot.value作为字符串;
    updateOnChanged(值);
    });
    }
    saveOnChanged(字符串值)异步{
    等待参考设置(值);
    }
    updateOnChanged(字符串值)异步{
    设置状态(){
    _todoController.value=\u todoController.value.copyWith(
    文本:值,
    );
    });
    }
    @凌驾
    小部件构建(构建上下文){
    返回脚手架(
    appBar:appBar(
    标题:文本(“待办事项屏幕”),
    ),
    正文:中(
    子:容器(
    填充:所有边缘设置(10.0),
    孩子:TextField(
    装饰:输入装饰(标签文本:“TODO”),
    最大行数:5,
    onChanged:saveOnChanged,
    控制器:\u todoController,
    ),
    ),
    ),
    );
    }
    @凌驾
    无效处置(){
    _todoController.dispose();
    如果(_subscription!=null)_subscription.cancel();
    super.dispose();
    }
    }
    

    希望一切顺利

    首先,为
    文本字段
    提供一个
    文本编辑控制器
    (查看完整示例)

    对于问题的第一部分,您需要向
    文本编辑控制器
    提供一个
    侦听器
    。此
    侦听器应触发如下函数:

      Future<void> _updateTaskValue(String text) {
        Firestore().runTransaction((Transaction transaction) {
          Firestore.instance.document([PATH OF YOUR DOCUMENT]).updateData({"todo": text});
        });
      }
    
    每次更新内容时(无论当前用户更新
    文本字段
    ,其他用户更新,还是从后台手动更新),此订阅都将触发一个功能

    下面调用的函数只是用新内容更新控制器的
    文本
    属性:

    void _onDatabaseUpdate(DocumentSnapshot snapshot) {
      setState(() {
        _controller.text = snapshot.data["todo"];
      });
    }
    
    有关完整示例,请参见

    void _onDatabaseUpdate(DocumentSnapshot snapshot) {
      setState(() {
        _controller.text = snapshot.data["todo"];
      });
    }