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

如何在Flutter Firebase手机认证(GetX)中添加圆形进度指示器

解决GetX+Firebase手机认证进度指示器不显示的问题

你的代码存在几处关键问题导致进度指示器无法正常工作,以下是具体修正方案:

核心问题分析

  1. 加载状态赋值错误:使用isloading.isTrue;仅为读取状态操作,并未实际修改isloading的值,正确赋值方式应为isloading.value = true/false;
  2. 加载状态未覆盖全流程分支:verifyPhoneNumber的异步流程包含多个分支(验证完成、验证失败、发送验证码),需在每个分支中正确更新加载状态,避免出现加载状态一直为true的僵死情况
  3. 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) {}));
  }
}

修正说明

  1. 正确更新加载状态:所有修改isloading的操作均改为isloading.value = true/false;,确保状态能被Obx监听并实时更新UI
  2. 覆盖全流程分支:在verificationCompleted、verificationFailed、codeSent分支中分别处理加载状态,避免状态僵死
  3. OTP验证添加加载状态:用户点击OTP提交按钮时开启加载,验证完成或失败后关闭,让用户清晰感知操作进度

UI代码无需修改

你的UI部分代码逻辑正确,Obx会自动监听isloading的变化,自动切换显示进度指示器或「创建账户」按钮。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 23:15:55