首页 文章

使用 Flutter 将表单上传到 Firestore

提问于
浏览
0

我对如何在我的 flutter 应用程序中将表单上传到 Firestore 感到困惑。我已经浏览了很多教程,并且能够登录 Firebase 并将数据从 Firestore 检索到我的 flutter 应用程序中,但我无法弄清楚如何将包含大量文本字段的表单上传到 Firestore。

示例:文档标题“书籍”文本字段包括:标题,作者等。

*** //以下是我从 Firestore 导入数据的页面(这是有效的)。我添加了一个按钮,它转到另一个页面,我试图添加一个表单上传到 Firestore(这不起作用)。加载页面有效,但未设置上传到 Firestore。

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'dart:async';

class FireStore extends StatelessWidget {
  FireStore({this.auth, this.onSignedOut});
  final BaseAuth auth; 
  final VoidCallback onSignedOut;

  void _signOut () async {
    try {
      await auth.signOut();
      onSignedOut();
    } catch (e) {
      print (e);
    }
  }

  @override
    Widget build(BuildContext context) {
      return new Scaffold(
        appBar: new AppBar(
          title: new Text ('Welcome'),
          actions: <Widget>[

          new FlatButton(
            child: new Text('Logout', style: new TextStyle(fontSize: 17.0, color: Colors.white)),
            onPressed: _signOut
          )
          ]
        ),
        body: new StreamBuilder(
          stream: Firestore.instance.collection('books').snapshots(),
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (!snapshot.hasData) return CircularProgressIndicator();
        return new GridView.count(
          crossAxisCount: 2,
          childAspectRatio: 1.0,
          padding: const EdgeInsets.all(4.0),
          mainAxisSpacing: 4.0,
          crossAxisSpacing: 4.0,

          children: snapshot.data.documents.map((DocumentSnapshot document) {
            return new ListTile(
              title: new Text(document['title']),
              subtitle: new Text(document['author']),

            );

          }).toList(),
        );
      },
    ),
    floatingActionButton: new FloatingActionButton(
      elevation: 0.0,
      child: new Icon(Icons.add),
      backgroundColor: new Color(0xFFE57373),
      onPressed: (){
        Navigator.push(
        context,
        new MaterialPageRoute(builder: (context) => new UploadFormField()),
        );

      }
    )
      );
      }

} 

// UPLOAD TO FIRESTORE

class UploadFormField extends StatefulWidget {
  @override
  _UploadFormFieldState createState() => _UploadFormFieldState();
}

class _UploadFormFieldState extends State<UploadFormField> {
  GlobalKey<FormState> _key = GlobalKey();
  bool _validate = false;
  String title, author;
  @override
Widget build(BuildContext context) {

  return MaterialApp(
    home: new Scaffold(
      appBar: new AppBar(
        title: new Text('Upload'),
      ),
      body: new SingleChildScrollView(
       child: new Container(
         margin: new EdgeInsets.all(15.0),
         child: new Form(
           key: _key,
           autovalidate: _validate,

         child: FormUI(

         )),
       ),

      ),

      ),
    );
  }
  Widget FormUI() {
    return new Column(
      children: <Widget>[
        new TextFormField(
          decoration: new InputDecoration(hintText: 'Title'),
          validator: validateTitle,
          onSaved: (String val) {
            title = val;
          }
        ),

        new TextFormField(
          decoration: new InputDecoration(hintText: 'Author'),
          validator: validateAuthor,
          onSaved: (String val) {
            author = val;
          }
        ),
        new SizedBox(height: 15.0),
        new RaisedButton(onPressed: _sendToServer, child: new Text('Upload'),
        )
      ],
    );
  }
  String validateTitle (String value) {
    String pattern = r' (^[a-zA-Z ]*$)';
    RegExp regExp = new RegExp(pattern);
    if (value.length == 0){
             return 'Title is required';

           } else if (!regExp.hasMatch(value)) {
             return "Title must be a-z and A-Z";
           }

           return null;
  }

  String validateAuthor (String value) {
    String pattern = r' (^[a-zA-Z ]*$)';
    RegExp regExp = new RegExp(pattern);
    if (value.length == 0){
             return 'Author is required';

           } else if (!regExp.hasMatch(value)) {
             return "Author must be a-z and A-Z";
           }

           return null;
  }

  _sendToServer(){
    if (_key.currentState.validate() ){
      //No error in validator
      _key.currentState.save();
      print ("Title $title");
      print ("Author $author");
    } else {
      // validation error
      setState(() {
              _validate = true;
            });
    }

  }
}

2 回答

  • 0

    Flutter 的 Firestore 插件将 Map 作为 setData 的输入或添加函数,因此无论您在类对象或其他变量中拥有什么数据,您只需将其转换为 map(或嵌套数据结构的嵌套映射)并将其转换为 setData 或 add 作为保存在 Firestore 中的输入。对于类,sputter 示例显示大多数在类中实现“toMap()”函数,它只返回所需的数据类对象在所需的地图结构中,以及它的对应“fromMap(Map mapData”“,当你获取时,它将用于从地图创建对象稍后来自 Firestore 的数据。

    例如。

    await Firestore.instance
        .collection(TBL_USERS)
        .add({
          "type": "Dog",
          "age": 6,
          "breed": "abc",
        });
    

    或者从它的地图开始,你可以直接使用任何字符串(只要它在地图中的唯一性)作为关键字

    例如。

    await Firestore.instance
        .collection(TBL_USERS)
        .add({
          "Dog": {
                  "age": 6,
                  "breed": "abc",
                 },
          "Cat" : {
                  "age": 2,
                  "breed": "xyz",
                 },
        });
    
  • 0

    我能够用以下方法解决这个问题:

    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    import 'auth.dart';
    import 'package:cloud_firestore/cloud_firestore.dart';
    import 'dart:async';
    
    class FireStore extends StatelessWidget {
      FireStore({this.auth, this.onSignedOut});
      final BaseAuth auth; 
      final VoidCallback onSignedOut;
    
      void _signOut () async {
        try {
          await auth.signOut();
          onSignedOut();
        } catch (e) {
          print (e);
        }
      }
    
      @override
        Widget build(BuildContext context) {
          return new Scaffold(
            appBar: new AppBar(
              title: new Text ('Welcome'),
              actions: <Widget>[
    
              new FlatButton(
                child: new Text('Logout', style: new TextStyle(fontSize: 17.0, color: Colors.white)),
                onPressed: _signOut
              )
              ]
            ),
            body: new StreamBuilder(
              stream: Firestore.instance.collection('books').snapshots(),
          builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
            if (!snapshot.hasData) return CircularProgressIndicator();
            return new GridView.count(
              crossAxisCount: 2,
              childAspectRatio: 1.0,
              padding: const EdgeInsets.all(4.0),
              mainAxisSpacing: 4.0,
              crossAxisSpacing: 4.0,
    
              children: snapshot.data.documents.map((DocumentSnapshot document) {
                return new ListTile(
                  title: new Text(document['title']),
                  subtitle: new Text(document['author']),
    
                );
    
              }).toList(),
            );
          },
        ),
        floatingActionButton: new FloatingActionButton(
          elevation: 0.0,
          child: new Icon(Icons.add),
          backgroundColor: new Color(0xFFE57373),
          onPressed: (){
            Navigator.push(
            context,
            new MaterialPageRoute(builder: (context) => new UploadFormField()),
            );
    
          }
        )
          );
          }
    
    } 
    
    // UPLOAD TO FIRESTORE
    
    class UploadFormField extends StatefulWidget {
      @override
      _UploadFormFieldState createState() => _UploadFormFieldState();
    }
    
    class _UploadFormFieldState extends State<UploadFormField> {
      GlobalKey<FormState> _key = GlobalKey();
      bool _validate = false;
      String title, author;
    
      @override
    Widget build(BuildContext context) {
    
      return MaterialApp(
        home: new Scaffold(
          appBar: new AppBar(
            title: new Text('Upload'),
          ),
          body: new SingleChildScrollView(
              child: new Container(
                margin: new EdgeInsets.all(15.0),
                child: new Form(
                  key: _key,
                  autovalidate: _validate,
                  child: FormUI(),
    
                ),
              ),
            ),
          ),
        );
      }
      Widget FormUI() {
        return new Column(
          children: <Widget>[
            new TextFormField(
              decoration: new InputDecoration(hintText: 'Title'),
              validator: validateTitle,
              onSaved: (String val) {
                title = val;
              }
            ),
    
            new TextFormField(
              decoration: new InputDecoration(hintText: 'Author'),
              validator: validateAuthor,
              onSaved: (String val) {
                author = val;
              }
            ),
            new SizedBox(height: 15.0),
            new RaisedButton(onPressed: _sendToServer, child: new Text('Upload'),
            )
          ],
        );
      }
      String validateTitle(String value) {
        String patttern = r'(^[a-zA-Z ]*$)';
        RegExp regExp = new RegExp(patttern);
        if (value.length == 0) {
          return "Title is Required";
        } else if (!regExp.hasMatch(value)) {
          return "Title must be a-z and A-Z";
        }
        return null;
      }
    
       String validateAuthor(String value) {
        String patttern = r'(^[a-zA-Z ]*$)';
        RegExp regExp = new RegExp(patttern);
        if (value.length == 0) {
          return "Author is Required";
        } else if (!regExp.hasMatch(value)) {
          return "Author must be a-z and A-Z";
        }
        return null;
      }
    
     _sendToServer(){
        if (_key.currentState.validate() ){
          //No error in validator
          _key.currentState.save();
          Firestore.instance.runTransaction((Transaction transaction) async {
            CollectionReference reference = Firestore.instance.collection('books');
    
            await reference.add({"Title": "$title", "Author": "$author"});
          });
        } else {
          // validation error
          setState(() {
                  _validate = true;
                });
        }
    
      }
    }
    

相关问题