Flutter FutureBuilder导致一秒钟的空异常

问题描述


class MyClass extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var _usersnapshot;
    List<dynamic> myContactsList;
    return StreamProvider<DocumentSnapshot>.value(
      value: DatabaseService("").myUser,builder: (context,child) => Expanded(
        child: Container(
            child: (_usersnapshot = Provider.of<DocumentSnapshot>(context)) ==
                        null ||
                    (myContactsList = _usersnapshot.data["contacts"]) == null
                ? Padding(
                    // if no contacts were found
                    padding: EdgeInsets.all(10.0),child: Column(
                      children: <Widget>[
                        Text(
                          "No recent chats yet",),],)
                : ListView.builder(
                    itemCount: _usersnapshot.data["contacts"].length,itemBuilder: (context,index) => FutureBuilder(
                      future: DatabaseService("").getUserById(
                        myContactsList.elementAt(index),snapshot) => GestureDetector(
                        onTap: () => Navigator.push(
                          context,MaterialPageRoute(
                            builder: (_) => ChatScreen(
                              myContactsList.elementAt(index),snapshot.data["displayName"],child: Container(
                          margin: EdgeInsets.only(top: 5,bottom: 5,right: 20),child: Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,children: <Widget>[
                              Row(
                                children: <Widget>[
                                  FutureBuilder(
                                    future: DatabaseService("").getUserById(
                                      myContactsList.elementAt(index),snapshot) =>
                                        CircleAvatar(
                                      radius: 33,backgroundImage: snapshot
                                                  .data["imageUrl"] ==
                                              null
                                          ? snapshot.data["isMale"] == true
                                              ? Assetimage(
                                                  "assets/images/male.png")
                                              : Assetimage(
                                                  "assets/images/female.png")
                                          : Assetimage(
                                              "assets/images/male.png"),SizedBox(width: 10),Column(
                                    crossAxisAlignment:
                                        CrossAxisAlignment.start,children: [
                                      FutureBuilder<DocumentSnapshot>(
                                        future: DatabaseService("").getUserById(
                                          myContactsList.elementAt(index),snapshot) => Text(
                                          snapshot.data["displayName"],style: TextStyle(
                                            color: Colors.grey,fontSize: 18,fontWeight: FontWeight.bold,SizedBox(height: 5),Container(
                                        width:
                                            MediaQuery.of(context).size.width *
                                                0.45,child: Text(
                                          "Something N. $index ",style: TextStyle(
                                            color: Colors.blueGrey,fontWeight: FontWeight.w600,overflow: TextOverflow.ellipsis,Column(
                                children: <Widget>[
                                  Text(
                                    "TIME"
                                  ),Container(
                                    height: 20,width: 40,decoration: Boxdecoration(
                                      color: Theme.of(context).primaryColor,borderRadius: BorderRadius.circular(30),alignment: Alignment.center,child: Text(
                                      "NEW",style: TextStyle(
                                        color: Colors.white,fontSize: 11,);
  }
}

每次与我的应用进行交互并在云Firestore DB中触发更改时,我都会使用StreamProvider()获取快照。当发生这种情况时,我在下面列出了一些异常,但是半秒钟后屏幕已修复,这可能是我猜出新快照的原因。 就像下面列出的一样,问题来自我使用的FutureBuilder()。 这是错误

The following NoSuchMethodError was thrown building FutureBuilder<DocumentSnapshot>(dirty,state: _FutureBuilderState<DocumentSnapshot>#98dd9):
The method '[]' was called on null.
Receiver: null
Tried calling: []("imageUrl")

The relevant error-causing widget was: 
  FutureBuilder<DocumentSnapshot> file:///home/pss/Desktop/android/Flutter_firebase_chat_app/lib/widgets/recent_chats.dart:90:35
When the exception was thrown,this was the stack: 
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1      RecentChats.build.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:Flutter_firebase_chat_app/widgets/recent_chats.dart:98:56)
#2      _FutureBuilderState.build (package:Flutter/src/widgets/async.dart:740:55)
#3      StatefulElement.build (package:Flutter/src/widgets/framework.dart:4663:28)
#4      ComponentElement.performRebuild (package:Flutter/src/widgets/framework.dart:4546:15)
...
════════════════════════════════════════════════════════════════════════════════════════════════════

Another exception was thrown: NoSuchMethodError: The method '[]' was called on null.

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The method '[]' was called on null.
Receiver: null
Tried calling: []("displayName")
The relevant error-causing widget was: 
  FutureBuilder<DocumentSnapshot> file:///home/pss/Desktop/android/Flutter_firebase_chat_app/lib/widgets/recent_chats.dart:114:39

错误指向以下两行: backgroundImage: snapshot.data["imageUrl"] == nullbuilder: (context,snapshot) => Text(snapshot.data["displayName"]

因此,我不确定自己是否诚实。我认为这是FutureBuilder()的原因,没有它们,我也不会例外。 我是Flutter的新手,因此任何建议将不胜感激!

解决方法

您要呼叫_userSnapshot.data[],但datanull,因此必须首先确保_userSnapshot不为null,也要确保_userSnapshot.data
同时,考虑放置一个加载器,您可以使用CircularProgressIndicator作为简单的开始,也可以使用pub.dev中的Shimmer库进行一些很酷的占位符加载动画(如Facebook)。

,

您可以将initialData参数设置为StreamProvider,在流还没有发出任何东西的情况下使用此数据。 您还应该在访问_userSnapshot.data!= null之前检​​查其键之一。