Flutter中Firebase Phone Auth实现OTP输入框自动填充求助
解决Flutter Firebase Phone Auth OTP自动填充问题
1. 先搞定平台配置(这步必须做)
Android端
- 打开
android/app/src/main/AndroidManifest.xml,给OTP页面对应的Activity(一般是MainActivity)加个intent-filter,让系统能把短信里的OTP定向到你的应用:
<activity android:name=".MainActivity" android:exported="true"> <!-- 保留原有配置 --> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <!-- 替换成你的应用包名,比如com.example.myapp --> <data android:scheme="your_package_name" /> </intent-filter> </activity>
- 另外注意短信格式:Firebase默认的短信是
[你的应用名] 你的验证码是 123456。,这个格式系统能识别;如果自定义短信模板,必须包含“验证码”或“code”这类关键词,且数字位数和你的OTP输入框一致(比如6位)。
iOS端
- 打开
ios/Runner/Info.plist,添加以下配置,允许应用读取并处理OTP:
<key>NSUserActivityTypes</key> <array> <string>$(PRODUCT_BUNDLE_IDENTIFIER).otp-authentication</string> </array> <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <!-- 替换成你的应用Bundle ID,比如com.example.myapp --> <string>your_bundle_id</string> </array> </dict> </array>
- iOS 12+支持自动填充,后续代码里要给OTP输入框设置正确的
textContentType。
2. 代码层面实现自动填充
方法一:用Firebase Auth自带的自动监听
Firebase的verifyPhoneNumber本身就有自动捕获OTP的回调,不用自己读短信。修改你的AuthController里的signInWithPhoneNumber方法:
Future<void> signInWithPhoneNumber(String phoneNumber, BuildContext context) async { await FirebaseAuth.instance.verifyPhoneNumber( phoneNumber: phoneNumber, verificationCompleted: (PhoneAuthCredential credential) async { // 系统自动获取到OTP时触发 await FirebaseAuth.instance.signInWithCredential(credential); // 把OTP传到OTP页面填充(这里用GetX做状态管理示例,你可以换成自己的状态管理方式) if (context.mounted) { String otp = credential.smsCode!; Get.find<AuthController>().autoFilledOTP = otp; Navigator.push(context, MaterialPageRoute(builder: (_) => OTPScreen())); } }, verificationFailed: (FirebaseAuthException e) { print(e.message); // 处理验证失败逻辑 }, codeSent: (String verificationId, int? resendToken) { _verificationId = verificationId; Navigator.push(context, MaterialPageRoute(builder: (_) => OTPScreen())); }, codeAutoRetrievalTimeout: (String verificationId) { _verificationId = verificationId; }, timeout: const Duration(seconds: 60), ); }
方法二:适配otp_text_field组件填充
在OTPScreen里用组件的控制器来设置自动获取到的OTP:
import 'package:otp_text_field/otp_text_field.dart'; import 'package:otp_text_field/style.dart'; class OTPScreen extends StatefulWidget { @override State<OTPScreen> createState() => _OTPScreenState(); } class _OTPScreenState extends State<OTPScreen> { late OTPController otpController; @override void initState() { super.initState(); otpController = OTPController(); // 从AuthController拿到自动填充的OTP,填充到输入框 String? autoOtp = Get.find<AuthController>().autoFilledOTP; if (autoOtp != null) { otpController.set(autoOtp.split('')); } } @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ OTPTextField( controller: otpController, length: 6, width: MediaQuery.of(context).size.width, fieldWidth: 50, style: const TextStyle(fontSize: 17), textFieldAlignment: MainAxisAlignment.spaceAround, fieldStyle: FieldStyle.box, textInputType: TextInputType.number, // iOS必须加这个,让系统识别是OTP输入框 textContentType: TextContentType.oneTimeCode, onCompleted: (pin) { Get.find<AuthController>().verifyOTP(pin); }, ), ], ), ); } }
方法三:用插件手动读短信(备选,不推荐)
如果上面的方法都不行,可以用sms_autofill插件辅助:
- 安装插件:
flutter pub add sms_autofill - 在OTPScreen里使用:
import 'package:sms_autofill/sms_autofill.dart'; import 'package:otp_text_field/otp_text_field.dart'; class OTPScreen extends StatefulWidget { @override State<OTPScreen> createState() => _OTPScreenState(); } class _OTPScreenState extends State<OTPScreen> with CodeAutoFill { late OTPController otpController; @override void initState() { super.initState(); otpController = OTPController(); listenForCode(); // 开始监听短信 } @override void codeUpdated() { // 拿到短信里的OTP,直接填充 if (code != null) { otpController.set(code!.split('')); } } @override void dispose() { cancel(); // 销毁时取消监听 super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ OTPTextField( controller: otpController, length: 6, // 其他配置同上 ), ], ), ); } }
3. 踩坑提醒
- 测试用的设备要开系统默认短信应用,第三方短信APP可能会拦截自动填充。
- Android模拟器上要手动发符合格式的短信,比如
[MyApp] 你的验证码是 123456。 - iOS要开启“自动填充密码”功能(设置→密码→自动填充密码)。
内容的提问来源于stack exchange,提问作者alex
相关产品推荐
相关产品推荐

