получение данных из firebase дает ноль, но после горячей перезагрузки работает нормально - PullRequest
0 голосов
/ 29 сентября 2018

после того, как я получил свои данные из firebase, данные становятся нулевыми, но если я перезагружаюсь, все работает нормально.если я комментирую строки с проблемами, то код работает нормально и правильно отправляет данные в firebase
Я пробовал много методов, пытаясь initState для setState, но безрезультатно.Я даже предполагал, что сборка была сделана до получения данных из firebase, но насколько я знаю, initState должен решить эту проблему.Я думаю, что я что-то здесь упускаю.: (

РЕДАКТИРОВАТЬ: это мое новое приложение, использующее futureBuilder, но виджет загружается до того, как данные

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_test/flutter_test.dart';

class UnlockDoor extends StatefulWidget {
  UnlockDoorState createState() => new UnlockDoorState();
}

class UnlockDoorState extends State<UnlockDoor> {
  final formKey = GlobalKey<FormState>();
  String building;
  String room;
  String name;
  String email;
  DateTime created;
  String comment;
  String uid;

  @override
  void initState() {
    FirebaseAuth.instance.currentUser().then((FirebaseUser user) {
      this.uid = user.uid;
    });
    Firestore.instance.collection('Users').document(uid).get().then((data) {
      this.name = data['Name'];
      this.email = data['Email'];
      this.building = data['Building'];
      this.room = data['Room'];
    });
    print("uid $uid");
    super.initState();
  }

  void validateAndSubmit() async {
    created = DateTime.now();
    formKey.currentState.save();
    await Firestore.instance
        .collection('Requests')
        .document('UnlockDoor')
        .collection('UnlockDoor')
        .document()
        .setData({
      'Email': email,
      'Name': name,
      'Building': building,
      'Room': room,
      'Comment': comment,
      'Status': "Pending",
      'Created': created,
      'Housing_Emp': "",
      'UID': uid
    });
    Navigator.of(context).pop();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Unlock Door Request"),
      ),
      body: new FutureBuilder<DocumentSnapshot>(
        future: Firestore.instance.collection('Users').document(uid).get(),
        builder: (context, snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.none:
            case ConnectionState.active:
            case ConnectionState.waiting:
              return Center(child: CircularProgressIndicator());
            case ConnectionState.done:
              if (snapshot.hasError) {
                return Center(child: Text('Error: ${snapshot.error}'));
              } else {
                print("why give null $name");
                return new Container(
                  padding: EdgeInsets.only(top: 60.0, left: 20.0, right: 20.0),
                  child: new Form(
                    key: formKey,
                    child: new ListView(
                      children: <Widget>[
                        Text(
                          'Requesting Door Unlock:',
                          style: TextStyle(
                            fontSize: 20.0,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                        SizedBox(height: 15.0),
                        Text(
                          "building: $building, Room: $room",
                          style: TextStyle(
                            fontSize: 15.0,
                            fontStyle: FontStyle.italic,
                          ),
                        ),
                        TextFormField(
                          maxLength: 200,
                          onSaved: (value) => comment = value,
                          decoration: InputDecoration(
                            labelText: 'Comment (optional)',
                            labelStyle: TextStyle(
                                fontSize: 18.0,
                                fontWeight: FontWeight.bold,
                                color: Colors.black54),
                          ),
                        ),
                        Container(
                          height: 50.0,
                          width: 130.0,
                          child: RaisedButton(
                              child: Text(
                                'Send Request',
                                style: TextStyle(
                                  fontSize: 15.0,
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                              splashColor: Colors.lightGreen,
                              onPressed: () {
                                _handlePressed(context);
                              }),
                        ),
                      ],
                    ),
                  ),
                );
              }
          }
        },
      ),
    );
  }

  void _handlePressed(BuildContext context) {
    confirmDialog(context).then((bool value) async {
      if (value) {
        validateAndSubmit();
      }
    });
  }
}

Future<bool> confirmDialog(BuildContext context) {
  return showDialog<bool>(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return new AlertDialog(
          title: new Text("Send Request"),
          actions: <Widget>[
            new FlatButton(
              child: Text("Yes"),
              onPressed: () => Navigator.of(context).pop(true),
            ),
            new FlatButton(
              child: Text("No"),
              onPressed: () => Navigator.of(context).pop(false),
            ),
          ],
        );
      });
}

1 Ответ

0 голосов
/ 29 сентября 2018

Вы пытаетесь получить задачу document in async , и вы используете это значение в представлении (виджет).Пока document не будет извлечено из Firebase , значение документа будет null .

Возможные решения:

  1. Используйте нулевые проверки и обрабатывайте в виджете (не рекомендуется)
  2. Используйте FutureBuilder , который идеально подходит для вашего случая использования.Например, см.

Я отредактировал ваш код.Взгляните

class UnlockDoorState extends State<UnlockDoor> {
  final formKey = GlobalKey<FormState>();
  String building;
  String room;
  String name;
  String email;
  DateTime created;
  String comment;
  String uid;
  Future data; //changed

  @override
  void initState() {
    super.initState();
    data = getDataFromFb(); //changed
  }

  Future<void> getDataFromFb() async {  //changed
    FirebaseUser user = await FirebaseAuth.instance.currentUser();
    this.uid = user.uid;
    var data = Firestore.instance.collection('Users').document(uid).get();
    this.name = data['Name'];
    this.email = data['Email'];
    this.building = data['Building'];
    this.room = data['Room'];
    return;
  }

  void validateAndSubmit() async {
    created = DateTime.now();
    formKey.currentState.save();
    await Firestore.instance
        .collection('Requests')
        .document('UnlockDoor')
        .collection('UnlockDoor')
        .document()
        .setData({
      'Email': email,
      'Name': name,
      'Building': building,
      'Room': room,
      'Comment': comment,
      'Status': "Pending",
      'Created': created,
      'Housing_Emp': "",
      'UID': uid
    });
    Navigator.of(context).pop();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Unlock Door Request"),
      ),
      body: new FutureBuilder<DocumentSnapshot>(
        future: data, //changed
        builder: (context, snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.none:
            case ConnectionState.active:
            case ConnectionState.waiting:
              return Center(child: CircularProgressIndicator());
            case ConnectionState.done:
              if (snapshot.hasError) {
                return Center(child: Text('Error: ${snapshot.error}'));
              } else {
                print("why give null $name");
                return new Container(
                  padding: EdgeInsets.only(top: 60.0, left: 20.0, right: 20.0),
                  child: new Form(
                    key: formKey,
                    child: new ListView(
                      children: <Widget>[
                        Text(
                          'Requesting Door Unlock:',
                          style: TextStyle(
                            fontSize: 20.0,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                        SizedBox(height: 15.0),
                        Text(
                          "building: $building, Room: $room",
                          style: TextStyle(
                            fontSize: 15.0,
                            fontStyle: FontStyle.italic,
                          ),
                        ),
                        TextFormField(
                          maxLength: 200,
                          onSaved: (value) => comment = value,
                          decoration: InputDecoration(
                            labelText: 'Comment (optional)',
                            labelStyle: TextStyle(
                                fontSize: 18.0,
                                fontWeight: FontWeight.bold,
                                color: Colors.black54),
                          ),
                        ),
                        Container(
                          height: 50.0,
                          width: 130.0,
                          child: RaisedButton(
                              child: Text(
                                'Send Request',
                                style: TextStyle(
                                  fontSize: 15.0,
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                              splashColor: Colors.lightGreen,
                              onPressed: () {
                                _handlePressed(context);
                              }),
                        ),
                      ],
                    ),
                  ),
                );
              }
          }
        },
      ),
    );
  }

  void _handlePressed(BuildContext context) {
    confirmDialog(context).then((bool value) async {
      if (value) {
        validateAndSubmit();
      }
    });
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...