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

Flutter Build Widget中异步判断用户存在状态失效问题求助

问题描述

我编写了一个返回bool值的异步函数isExist,在Build Widget的条件判断中使用该函数,但代码始终返回SignIn组件。已知user不为null且用户确实存在,checkIfUserExist函数在其他页面可正常运行,相关代码如下:

Future isExist(uid) async{
    var isExist = await Database().checkIfUserExist(uid);
    if(isExist == true){
      return true;
    }
    else{
      return false;
    }
  }
  @override
  Widget build(BuildContext context) {

    final user = Provider.of<UserDashboard?>(context);
    // return either Home or Authenticate widget
    if(user == null){
      print("user null");
      return SignIn();
    }else{
      print("user not null");
      if(isExist(user.uid) == Future.value(true)){
        return Home();
      }
    }
    return SignIn();
  }
Future<bool> checkIfUserExist(String adminID) async{
bool isExist = false;
try{
  await admin.doc(adminID).get()
    .then((doc) => isExist = doc.exists);
  return isExist;
}catch(e){
  print(e);
  return isExist;
}
}
问题原因
  • 异步对象引用比较错误:isExist(user.uid)返回的是一个Future<bool>实例,Future.value(true)是另一个全新的Future实例,两个对象的内存引用不同,==比较永远不成立,导致条件判断失败。
  • Build方法无法直接处理异步操作:Build方法是同步执行的生命周期方法,不能直接使用await等待异步结果,否则会阻塞UI渲染流程。
解决方案

使用FutureBuilder组件处理异步逻辑,它能根据Future的执行状态(等待、成功、失败)动态返回对应UI:

修改主组件代码

// 简化isExist函数,直接返回checkIfUserExist的结果
Future<bool> isExist(String uid) async {
  return await Database().checkIfUserExist(uid);
}

@override
Widget build(BuildContext context) {
  final user = Provider.of<UserDashboard?>(context);

  if (user == null) {
    print("user null");
    return SignIn();
  }

  print("user not null");
  return FutureBuilder<bool>(
    future: isExist(user.uid),
    builder: (context, snapshot) {
      // 异步请求未完成时,显示加载状态
      if (snapshot.connectionState == ConnectionState.waiting) {
        return const CircularProgressIndicator(); // 可替换为自定义加载UI
      }

      // 请求完成后根据结果返回对应页面
      return snapshot.data == true ? Home() : SignIn();
    },
  );
}

优化checkIfUserExist函数(可选)

去掉冗余的then回调,直接使用await处理文档查询结果:

Future<bool> checkIfUserExist(String adminID) async {
  try {
    final docSnapshot = await admin.doc(adminID).get();
    return docSnapshot.exists;
  } catch (e) {
    print(e);
    return false;
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 03:05:40