如何在Flutter Firebase手机认证(GetX)中添加圆形进度指示器
解决GetX+Firebase手机认证进度指示器不显示的问题
你的代码存在几处关键问题导致进度指示器无法正常工作,以下是具体修正方案:
核心问题分析
- 加载状态赋值错误:使用
isloading.isTrue;仅为读取状态操作,并未实际修改isloading的值,正确赋值方式应为isloading.value = true/false; - 加载状态未覆盖全流程分支:
verifyPhoneNumber的异步流程包含多个分支(验证完成、验证失败、发送验证码),需在每个分支中正确更新加载状态,避免出现加载状态一直为true的僵死情况 - OTP验证流程未处理加载状态:用户输入OTP后的验证过程也需显示加载状态,提升用户感知
修正后的AuthController代码
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:live_exam/Assets_Widget/logintextfeild.dart'; import 'package:live_exam/homepage.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:live_exam/login.dart'; import 'package:live_exam/loginfinal.dart'; import '../userdata/users.dart'; class AuthControler extends GetxController { // 文本控制器:收集用户信息并写入Firestore TextEditingController namecontroler = TextEditingController(); TextEditingController mobilecontroler = TextEditingController(); TextEditingController emailControler = TextEditingController(); TextEditingController addressControler = TextEditingController(); TextEditingController schoolnameControler = TextEditingController(); TextEditingController countrycode = TextEditingController(); TextEditingController pinControler = TextEditingController(); FirebaseAuth auth = FirebaseAuth.instance; RxBool isloading = false.obs; phoneauth(context) async { // 开启加载状态 isloading.value = true; await auth .verifyPhoneNumber( phoneNumber: mobilecontroler.text, timeout: const Duration(seconds: 60), verificationCompleted: ((PhoneAuthCredential credential) async { try { var result = await auth.signInWithCredential(credential); final firestore = FirebaseFirestore.instance; User? user = result.user; if (user != null) { await firestore.collection("Users").doc(user.uid).set({ "name": namecontroler.text, "phone": mobilecontroler.text, "email": emailControler.text, "address": addressControler.text, "institute": schoolnameControler.text }); Get.offAll(const HomePage()); } } catch (e) { Get.snackbar("Live exam", e.toString(), duration: const Duration(seconds: 5)); } finally { // 验证完成后关闭加载状态 isloading.value = false; } }), verificationFailed: (FirebaseException exception) { print(exception); Get.snackbar("Live exam", exception.toString(), duration: const Duration(seconds: 5)); // 验证失败时关闭加载状态 isloading.value = false; }, codeSent: ((String verificationId, int? forceResendingToken) { // 验证码发送成功,弹出OTP对话框后关闭加载状态(等待用户手动输入) isloading.value = false; final alertbox = AlertDialog( content: Container( width: 291.w, height: 349.h, child: Column( children: [ SizedBox(height: 31.h), Text( "Enter your verification OTP", style: TextStyle( fontSize: 18.sp, fontWeight: FontWeight.bold, fontFamily: 'Jaldi'), ), SizedBox(height: 19.h), OtpScreeen(controller: pinControler, hintText: "Enter OTP"), SizedBox(height: 20.h), ShahedButton3( ontap: () async { try { FocusManager.instance.primaryFocus?.unfocus(); // OTP验证开始时开启加载状态 isloading.value = true; Get.snackbar("Live Exam", "verifing.. OTP", duration: const Duration(seconds: 2)); final smscode = pinControler.text; PhoneAuthCredential phoneAuthCredential = PhoneAuthProvider.credential( verificationId: verificationId, smsCode: smscode); var result = await auth.signInWithCredential(phoneAuthCredential); final firestore = FirebaseFirestore.instance; User? user = result.user; if (user != null) { await firestore.collection("Users").doc(user.uid).set({ "name": namecontroler.text, "phone": mobilecontroler.text, "email": emailControler.text, "address": addressControler.text, "institute": schoolnameControler.text }); Get.offAll(const HomePage()); } } on FirebaseAuthException catch (e) { Get.snackbar("Live", e.toString(), duration: const Duration(seconds: 5)); } finally { // OTP验证完成/失败后关闭加载状态 isloading.value = false; } }, titile: "Submit") ], ), ), ); showDialog( context: context, builder: ((context) { return alertbox; })); }), codeAutoRetrievalTimeout: ((verificationId) {})); } }
修正说明
- 正确更新加载状态:所有修改
isloading的操作均改为isloading.value = true/false;,确保状态能被Obx监听并实时更新UI - 覆盖全流程分支:在
verificationCompleted、verificationFailed、codeSent分支中分别处理加载状态,避免状态僵死 - OTP验证添加加载状态:用户点击OTP提交按钮时开启加载,验证完成或失败后关闭,让用户清晰感知操作进度
UI代码无需修改
你的UI部分代码逻辑正确,Obx会自动监听isloading的变化,自动切换显示进度指示器或「创建账户」按钮。
内容的提问来源于stack exchange,提问作者md shahed
相关产品推荐
相关产品推荐

