Flutter使用Firebase Database时DataSnapshot相关代码报错求助
问题分析与修正方案
核心问题点
once()方法已废弃:新版Firebase Realtime Database Flutter SDK中,once()方法被移除,需使用get()方法获取单次数据,且返回值为DatabaseEvent,需通过event.snapshot获取数据快照。- 语法错误:
.then()闭包结尾符号错误,应为});而非};。 - 弹窗未正确关闭:登录时显示的ProgressBar未在后续流程中关闭,会导致多个弹窗叠加。
- 重复弹窗与冗余代码:验证用户存在时重复显示ProgressBar,属于冗余操作。
- 变量名不一致:代码中混用
firebaseAuth与_firebaseAuth,需保持统一。
修正后的完整代码
void loginRest(BuildContext context) async { final user = (await firebaseAuth.signInWithEmailAndPassword( email: emailTextController.text, password: passwordTextController.text, ).catchError((errMsg) { if (errMsg.code == "user-not-found") { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text( "Login Details are Incorrect", style: TextStyle( color: Colors.red, fontWeight: FontWeight.bold, fontSize: 18.0, ), ), ), ); } else if (errMsg.code == "wrong-password") { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text( "Password is Wrong", style: TextStyle( color: Colors.red, fontWeight: FontWeight.bold, fontSize: 18.0, ), ), ), ); } else if (errMsg.code == "invalid-email") { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text( "Email Format is not Valid", style: TextStyle( color: Colors.red, fontWeight: FontWeight.bold, fontSize: 18.0, ), ), ), ); } else { displayToastMessage("Error: $errMsg", context); } })).user; if (user != null) { // 显示加载弹窗 showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { return const ProgressBar( message: "Authenticating Please Wait...", ); }, ); // 使用get()替代once()获取数据 user_reference.child(user.uid).get().then((DatabaseEvent event) { DataSnapshot snap = event.snapshot; // 先关闭加载弹窗 Navigator.pop(context); if (snap.value != null) { Navigator.push( context, PageRouteBuilder( transitionDuration: const Duration(seconds: 1), transitionsBuilder: (context, animation, animationTime, child) { animation = CurvedAnimation( parent: animation, curve: Curves.fastLinearToSlowEaseIn, ); return ScaleTransition( scale: animation, alignment: Alignment.center, child: child, ); }, pageBuilder: (context, animation, animationTime) { return const HomeScreen(); }, ), ); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( "You have been logged in Successfully", style: TextStyle( color: Colors.green, fontWeight: FontWeight.bold, fontSize: 18.0, ), ), ), ); } else { await firebaseAuth.signOut(); displayToastMessage( "User doesn't exist, please create new account", context, ); } }).catchError((error) { // 关闭弹窗并处理数据库查询错误 Navigator.pop(context); displayToastMessage("Database Error: $error", context); }); } else { displayToastMessage("Error Occurred", context); } }
关键修改说明
- 替换
once()为get():get()方法返回DatabaseEvent,通过event.snapshot获取DataSnapshot,适配新版SDK。 - 关闭加载弹窗:在处理数据库返回结果前,先调用
Navigator.pop(context)关闭之前显示的ProgressBar,避免弹窗叠加。 - 修复语法错误:修正
.then()闭包结尾的符号错误,确保代码语法合规。 - 移除冗余弹窗:删除验证用户存在时重复显示的ProgressBar代码。
- 统一变量名:将
_firebaseAuth.signOut()改为firebaseAuth.signOut(),保持与前面的变量一致。 - 添加错误捕获:为数据库查询添加
catchError,处理可能的数据库请求错误。
内容的提问来源于stack exchange,提问作者Mr Fin
相关产品推荐
相关产品推荐

