我在适用于Android的Flutter应用程序中使用Firebase电话身份验证。登录系统正常运行。但是,每次我打开该应用程序时,它都会返回空用户。因此,每次打开应用程序时我都必须登录。我不知道这是错误还是错误,但是我会在这里与大家共享代码。
PhoneAuth代码:
enum PhoneAuthStatus {
SignedIn,
CodeSent,
HasError,
SignedOut,
}
class PhoneAuth with ChangeNotifier {
String verificationId;
final FirebaseAuth phoneAuth = FirebaseAuth.instance;
PhoneAuthStatus phoneAuthStatus = PhoneAuthStatus.SignedOut;
PhoneAuth.initialize() {
init();
}
Future<void> init() async {
currentUser = await phoneAuth.currentUser();
if (currentUser == null) {
phoneAuthStatus = PhoneAuthStatus.SignedOut;
notifyListeners();
} else {
phoneAuthStatus = PhoneAuthStatus.SignedIn;
}
}
PhoneAuthStatus get status => phoneAuthStatus;
FirebaseUser get user => currentUser;
Future<void> verifyPhoneNumber(String phNum) async {
phoneAuth.verifyPhoneNumber(
phoneNumber: phNum,
timeout: Duration(seconds: 90),
verificationCompleted: (AuthCredential phoneAuthCredential) async {
AuthResult authResult;
try {
authResult =
await phoneAuth.signInWithCredential(phoneAuthCredential);
} catch (error) {
phoneAuthStatus = PhoneAuthStatus.HasError;
notifyListeners();
return;
}
currentUser = authResult.user;
uid = currentUser.uid;
phoneAuthStatus = PhoneAuthStatus.SignedIn;
notifyListeners();
},
verificationFailed: (AuthException authException) {
print(authException.message);
phoneAuthStatus = (PhoneAuthStatus.HasError);
notifyListeners();
},
codeSent: (String vId, [int forceResendingToken]) async {
phoneAuthStatus = (PhoneAuthStatus.CodeSent);
notifyListeners();
verificationId = vId;
},
codeAutoRetrievalTimeout: (String vId) {
verificationId = vId;
});
return;
}
Future<void> signInWithPhoneNumber(String code) async {
final AuthCredential credential = PhoneAuthProvider.getCredential(
verificationId: verificationId,
smsCode: code.toString(),
);
AuthResult authResult;
try {
authResult = await phoneAuth.signInWithCredential(credential);
} catch (error) {
phoneAuthStatus = (PhoneAuthStatus.HasError);
notifyListeners();
return;
}
currentUser = authResult.user;
phoneAuthStatus = (PhoneAuthStatus.SignedIn);
notifyListeners();
return;
}
Future<void> signOut() async {
phoneAuth.signOut();
phoneAuthStatus = (PhoneAuthStatus.SignedOut);
notifyListeners();
}
}
main.dart代码:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider.value(value: PhoneAuth.initialize()),
],
child: MaterialApp(
title: app_name,
// routes: Routes.routes,
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
)
home: Container(
child: LocationError(currentWidget: HomePage()),
),
),
);
}
}
init()函数应返回PhoneAuthStatus.SignedIn。但是,由于currentUser为null,它返回PhoneAuthStatus.SignedOut。 请帮助我,告诉我我做错了什么。谢谢。
扑打医生:
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 1.20.0, on Microsoft Windows [Version 10.0.18363.959], locale en-US)
[!] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
X Android license status unknown.
Try re-installing or updating your Android SDK Manager.
See https://developer.android.com/studio/#downloads or visit https://flutter.dev/docs/get-started/install/windows#android-setup for detailed instructions.
[√] Android Studio (version 4.0)
[√] VS Code (version 1.47.3)
[!] Connected device
! No devices available
! Doctor found issues in 2 categories.
答案 0 :(得分:0)
您是否检查过将notifyListeners()
放在if块之外?
currentUser = await phoneAuth.currentUser();
if (currentUser == null) {
phoneAuthStatus = PhoneAuthStatus.SignedOut;
} else {
phoneAuthStatus = PhoneAuthStatus.SignedIn;
}
notifyListeners();
另一个猜测是,您正在init()方法内调用一个future方法。也许这就是为什么您总是将身份验证状态作为signOut的原因。
“ init 方法在设计上是同步的。您可以在覆盖的build方法中返回FutureBuilder小部件,而不是在 init 方法中创建FutureBuilder小部件。可以在这里免费查看FutureBuilder小部件的文档,以获取有关其工作方式的示例。”
因此,我认为最好使用将来的构建器来验证用户的存在。