Загрузить форму в Firestore с Flutter - PullRequest
0 голосов
/ 27 июня 2018

Я запутался в том, как загрузить форму в Firestore в моем приложении. Я прошел многочисленные уроки и могу войти в Firebase и получить данные из Firestore в мое приложение, но я не могу понять, как загрузить форму с многочисленными текстовыми полями в 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 голосов
/ 29 июня 2018

Я смог разобраться со следующим:

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

  }
}
0 голосов
/ 27 июня 2018

Плагин Flirester для Firestore принимает Map в качестве входных данных для setData или добавления функций, поэтому, какие бы данные у вас ни были в объекте класса или в других переменных, вам просто нужно преобразовать их в карту (или вложенную карту для вложенной структуры данных) и передать их setData или добавить функцию в качестве ввода для сохранения в Firestore. Для классов примеры трепетания показывают, в основном, функцию «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",
             },
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...