You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter使用StreamBuilder<QuerySnapshot>出现ArgumentError编译错误求助

Flutter StreamBuilder ArgumentError 错误分析与解决

错误原因定位

从错误堆栈和代码来看,有两个核心问题触发了ArgumentError:

  1. 无效列表索引:你定义了get index => null;,使用items[index]时相当于传入null作为列表索引,直接触发列表访问的参数错误(对应堆栈第97行)。
  2. 空列表访问风险:mail初始值为空格,initState异步获取SharedPreferences的过程中,第一次构建时Firestore会查询邮箱等于空格的用户,返回空文档列表,此时items[0]会因索引越界报错。

修复方案

1. 修正索引变量

删除错误的get index => null;定义,由于你通过邮箱查询单个用户(邮箱应为唯一标识),直接使用items[0]访问第一个文档即可,无需额外index变量。

2. 处理空列表与数据加载状态

在builder中,除了判断snapshot.hasData,还要检查返回的文档列表是否为空,避免索引越界;同时处理mail未加载完成的情况。

3. 优化邮箱初始状态

将mail初始值设为null,避免初始查询无效数据。

修改后的完整代码

class ProfileScreen extends StatefulWidget {
  @override
  _ProfileScreenState createState() => _ProfileScreenState();
}

class _ProfileScreenState extends State<ProfileScreen> {
  SharedPreferences prefs;
  AuthService _authService = AuthService();
  String mail; // 初始设为null

  Future getPrefs() async {
    prefs = await SharedPreferences.getInstance();
    setState(() {
      mail = prefs.getString('userMail');
    });
  }

  @override
  void initState() {
    super.initState();
    getPrefs();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Profilin'),
      ),
      body: SingleChildScrollView(
        child: Column(
          children: [
            Padding(
              padding: const EdgeInsets.all(5.0),
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: mail == null 
                    ? CircularProgressIndicator() // mail未加载时显示加载状态
                    : StreamBuilder<QuerySnapshot>(
                        stream: FirebaseFirestore.instance
                            .collection('User')
                            .where('email', isEqualTo: mail)
                            .snapshots(),
                        builder: (context, snapshot) {
                          if (snapshot.hasData) {
                            List<DocumentSnapshot> items = snapshot.data.docs;
                            if (items.isEmpty) {
                              return Text('用户不存在'); // 处理空列表情况
                            }
                            // 提取用户数据,避免重复访问items[0]
                            final userDoc = items[0];
                            return Column(
                              children: [
                                SizedBox(height: 20),
                                Row(
                                  children: [
                                    Expanded(
                                      flex: 2,
                                      child: Container(
                                        width: 120,
                                        height: 120,
                                        child: Card(
                                          child: Image(
                                            fit: BoxFit.cover,
                                            image: NetworkImage(
                                                'https://ui-avatars.com/api/?name=${userDoc.get('name')}&size=256&bold=true'),
                                            errorBuilder: (context, object, stackTrace){
                                              return Icon(Icons.person, size:75);
                                            },
                                            loadingBuilder: (context, child, loadingProgress){
                                              if(loadingProgress == null) return child;
                                              return CircularProgressIndicator();
                                            },
                                          ),
                                        ),
                                      ),
                                    ),
                                    SizedBox(width: 15),
                                    Expanded(
                                      flex: 5,
                                      child: Column(
                                        children: [
                                          Container(
                                            width: double.infinity,
                                            child: Text(
                                              userDoc.get('comment'),
                                              style: TextStyle(fontSize: 25),
                                            ),
                                          ),
                                          Container(
                                            width: double.infinity,
                                            child: Text(
                                              userDoc.get('email'),
                                              style: TextStyle(fontSize: 20),
                                            ),
                                          ),
                                        ],
                                      ),
                                    )
                                  ],
                                ),
                                SizedBox(height: 20),
                                Container(
                                  width: double.infinity,
                                  child: ElevatedButton(
                                    child: Text('Çıkış'),
                                    onPressed: () {
                                      prefs.setBool('isLogged', false);
                                      _authService.signOut();
                                      Navigator.pushNamed(context, myRouteNames.homeRoute);
                                    },
                                    style: ElevatedButton.styleFrom(
                                      backgroundColor: Theme.of(context).primaryColor,
                                      padding: EdgeInsets.symmetric(horizontal: 110),
                                      shape: RoundedRectangleBorder(
                                        borderRadius: BorderRadius.circular(25),
                                      ),
                                    ),
                                  ),
                                ),
                                SizedBox(height: 25),
                                ContainerWithTitle(
                                  title: 'Verilerin',
                                  widget: Padding(
                                    padding: const EdgeInsets.all(5.0),
                                    child: Column(
                                      children: [
                                        TargetButton(),
                                        Divider(),
                                        FavoritesButton(),
                                        Divider(),
                                        PlanButton(),
                                        Divider(),
                                        ExpensesButton()
                                      ],
                                    ),
                                  ),
                                )
                              ],
                            );
                          } else if (snapshot.hasError) {
                            return Text('加载出错: ${snapshot.error}'); // 处理错误状态
                          } else {
                            return CircularProgressIndicator();
                          }
                        },
                      ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者Golgi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 21:05:46