在initState中初始化变量

时间:2019-06-07 08:26:36

标签: firebase flutter google-cloud-firestore

我正在initState(){}中初始化变量:

@override
  void initState() {
    getDataFromFirestore();
    super.initState();

    });
  }

该方法是异步的,基本上是从Firestore获取数据,以便用数据填充对象“ _markerMap”。然后将此属性用作窗口小部件中的属性。这个小部件在我的build方法中被调用。

Widget build(BuildContext context) {
    return new Scaffold(
      body: MyWidget(
            markerMap: _markerMap)
     );
  ....
 }

MyWidget是日历。 markerMaps将图标添加到日历上的某些日期。标记有时仅添加到日历中。因此,故障是间歇性的。可以肯定地假设,在initState()中,数据将从Firestore加载以初始化Firestore中的变量。有什么想法可能会发生什么,为什么只有有时标记会出现在日历上?

添加设置了_markerMap的代码

getDataFromFirestore() async {
    await FirebaseAuth.instance.currentUser().then((user) {
      Firestore.instance.collection('availableDates').where('bandId', isEqualTo: user.uid).snapshots().listen(
              (data) => data.documents.forEach((doc) => _markerMap.add(
              doc['availableDates'].toDate(),
              Event(
                  date:doc['availableDates'].toDate(),
                  title: 'hello',
                  icon: _presentIcon(doc['availableDates'].toDate().day.toString())))));
      setState(() {});
    }).catchError((onError){
    });
  }

2 个答案:

答案 0 :(得分:1)

在initState中初始化变量没有任何错误,除非它们是静态的。因此,发生的事情是您最初已声明_markerMap,但是只有在一些异步函数getDataFromFirestore()之后才会初始化它,这可能需要几秒钟。在这里,您分配了markerMap: _markerMap,但最初_markerMap为null,仅在getDataFromFirestore()函数之后进行初始化。因此,检查空

是一个好习惯
_markerMap!=null?MyWidget(
            markerMap: _markerMap):Container();

或提供默认值

答案 1 :(得分:1)

正如我从您的getDataFromFirestore方法中看到的那样,您在获得User对象(setState调用)之后立即执行小部件重建(FirebaseAuth.instance.currentUser()调用)。

但是,您稍后会修改_markerMap变量-仅当您完成Firestore.instance.collection查询时。在这种情况下,setState调用现在是多余的。

setState回调中调用listen应该可以解决问题。

例如

final _markerMap = {};

getDataFromFirestore() async {
  await FirebaseAuth.instance.currentUser().then((user) {
    Firestore.instance
      .collection('availableDates')
      .where('bandId', isEqualTo: user.uid)
      .snapshots()
      .listen((data) => data.documents.forEach((doc) {
        setState(() { // Here is the setState call
          _markerMap.add(
            doc['availableDates'].toDate(),
            Event(
              date: doc['availableDates'].toDate(),
              title: 'hello',
              icon: _presentIcon(doc['availableDates'].toDate().day.toString())
            )
          );
        });
      }));
  }).catchError((onError) {});
}

请仔细检查此示例代码。我的一般建议是正确的,但是我并未对此进行测试。