How to sync Flutter TextField with Firestore field?

一世执手 提交于 2020-03-20 06:31:24

问题


I have task document in Firestore, which has todo field, and TextField in the Flutter UI.

Please advice how to make the textfield synced with the todo field, i.e.

  1. Any time, text in the textfield is changed as user's typing, update the todo field with the just typed value.
  2. Any time, the todo field is updated (manually in the Firestore console or by other user), update the textfield with the most recent value.

Thanks!


回答1:


First of all, supply a TextEditingController to the TextField (take a look at this for a complete example).

For the first part of the question, you will need to provide a listener to the TextEditingController. This listener should trigger a function like so :

  Future<void> _updateTaskValue(String text) {
    Firestore().runTransaction((Transaction transaction) {
      Firestore.instance.document([PATH OF YOUR DOCUMENT]).updateData({"todo": text});
    });
  }

Assuming that text is the controller's text value. Note that runTransaction is used to avoid data concurrency.

For the second part of the question, you will have to listen to the document. To do so, declare into initState a StreamSubscription :

subscription = Firestore.instance.document("").snapshots().listen(
    (DocumentSnapshot snapshot) => this._onDatabaseUpdate(snapshot));

This subscription will trigger a function each time the content is updated (whether the current user updates the TextField, another users updates it, or manually from the back office).

The function called below simply updates the controller's text attribute with the new content :

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

For a complete example, see this gist.




回答2:


  1. TextField onChanged updates the value in firebase.
  2. Listen for value change in firebase and update the value for TextField with TextEditingController.

Here is the code :

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();
  }
}

Hope it hepls!



来源:https://stackoverflow.com/questions/52456308/how-to-sync-flutter-textfield-with-firestore-field

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!