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

Flutter中使用Stream Provider时如何展示加载页避免报错

问题原因

你当前的报错核心是两个问题:

  • StreamProvider 初始数据设为 null,流还没返回数据时,Home 页面直接读取 null 的用户属性触发空安全报错
  • Provider.of 加了 listen: false 不会监听流的更新,就算后续流返回数据页面也不会刷新

修正方案

不需要用FutureBuilder,直接在读取流数据的页面加加载状态判断即可,调整后的代码如下:

// UserData类原有逻辑无需修改
class UserData {
  String uid;

  UserData(this.uid);

  Stream<UserModel> get getUserData{
    return FirebaseDatabase.instance.reference().child('users').child(uid).onValue.map((e) {
      return UserModel(e.snapshot.key, e.snapshot.value['name'],e.snapshot.value['Email']);
    });
  }
}

// MainPage类仅需要补全空安全适配即可,原有逻辑无需修改,注意确保传入的user.uid为有效非空值
class MainPage extends StatefulWidget {
  const MainPage({Key? key}) : super(key: key);
  @override
  _MainPageState createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  @override
  Widget build(BuildContext context) {
    return StreamProvider<UserModel?>.value(
      value: UserData(user.uid).getUserData,
      initialData: null,
      child: const Home(),
    );
  }
}

// Home类为核心调整部分
class Home extends StatefulWidget {
  const Home({Key? key}) : super(key: key);

  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  @override
  Widget build(BuildContext context) {
    // 去掉listen: false,开启监听流的更新
    final UserModel? userData = Provider.of<UserModel?>(context);
    
    // 数据为null时展示加载页面
    if (userData == null) {
      return const Scaffold(
        body: Center(
          child: CircularProgressIndicator(),
        ),
      );
    } 
    // 数据加载完成后走原有业务逻辑
    else {
      // 此处修正你原代码中user变量的笔误,替换为userData,可根据实际业务调整判断条件
      return userData.role == 'offer' ? const Offer() : const Customer();
    }
  }
}

额外优化建议

如果需要处理流加载出错的场景,可以将StreamProvider替换为StreamBuilder,额外增加错误状态处理:

class _MainPageState extends State<MainPage> {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder<UserModel>(
      stream: UserData(user.uid).getUserData,
      builder: (context, snapshot) {
        // 加载出错时展示错误页
        if (snapshot.hasError) {
          return Scaffold(body: Center(child: Text('加载失败:${snapshot.error}')));
        }
        // 加载中展示加载页
        if (!snapshot.hasData) {
          return const Scaffold(body: Center(child: CircularProgressIndicator()));
        }
        // 加载成功后传递数据
        return Provider.value(
          value: snapshot.data!,
          child: const Home(),
        );
      },
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 14:57:03