【问题标题】:getting data from firebase gives null but after hot reload work fine从firebase获取数据给出null但热重载后工作正常
【发布时间】:2018-09-28 21:49:20
【问题描述】:

在我从 firebase 获取数据后,数据为空,但如果我热重载它工作正常。如果我用问题评论代码行,则代码可以正常工作并将数据正确提交到 firebase
我尝试了许多方法试图将 initState 设置为 setState 但没有用。 我什至认为构建是在从 firebase 获取数据之前完成的,但据我所知,initState 应该可以解决这个问题。我想我在这里遗漏了一些东西。 :(

编辑: 这是我使用 futureBuilder 的新 attemet,仍然在数据之前加载小部件

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

【问题讨论】:

  • 你找到解决办法了吗?

标签: firebase flutter google-cloud-firestore


【解决方案1】:

您正在尝试在 async 任务中获取document,并且您正在视图(小部件)中使用该值。在从 Firebase 获取 document 之前,文档的值将为 null

可能的解决方案:

  1. 使用 null 检查 并在小部件中处理(不推荐)
  2. 使用非常适合您的用例的 FutureBuilder。例如,refer

我编辑了你的代码。看看

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

【讨论】:

  • 如果我使用流生成器会怎样?
猜你喜欢
  • 1970-01-01
  • 2022-01-22
  • 2020-10-31
  • 2021-09-26
  • 2021-04-01
  • 2018-05-20
  • 2021-09-27
  • 1970-01-01
  • 2021-10-12
相关资源
最近更新 更多