Flutter 在Future builder中使用本地身份验证是在身份验证后无限次调用本地身份验证

Flutter 在Future builder中使用本地身份验证是在身份验证后无限次调用本地身份验证,flutter,authentication,local,future,builder,Flutter,Authentication,Local,Future,Builder,我尝试在用户使用应用程序之前使用本地身份验证对其进行身份验证。但问题是,我必须使用Future Builder来检查用户数据,以便根据需要转到主屏幕或登录屏幕。因此,我必须在Future Builder中使用本地身份验证来验证用户。但这会导致在我到达主屏幕后无限次调用指纹验证。所以我们无法摆脱本地身份验证。请帮忙告诉我是否还有其他办法。提前感谢:) 类MyApp扩展StatefulWidget{ @凌驾 _MyAppState createState()=>\u MyAppState(); }

我尝试在用户使用应用程序之前使用本地身份验证对其进行身份验证。但问题是,我必须使用Future Builder来检查用户数据,以便根据需要转到主屏幕或登录屏幕。因此,我必须在Future Builder中使用本地身份验证来验证用户。但这会导致在我到达主屏幕后无限次调用指纹验证。所以我们无法摆脱本地身份验证。请帮忙告诉我是否还有其他办法。提前感谢:)

类MyApp扩展StatefulWidget{
@凌驾
_MyAppState createState()=>\u MyAppState();
}
类MyAppState扩展了状态{
最终AuthMethods_AuthMethods=AuthMethods();
最终本地身份验证_LocalAuthentication=LocalAuthentication();
bool\u hasFingerPrintSupport=false;
bool _authorizedOrNot=false;
List _availableBuimetricType=List();
@凌驾
void initState(){
super.initState();
_getBiometricsSupport();
_getAvailableSupport();
}
Future\u getBiometricsSupport()异步{
bool-hasnaftmentsupport=false;
试一试{
hasFingerPrintSupport=wait_localAuthentication.canCheckBiometrics;
}捕获(e){
印刷品(e);
}
如果(!已安装)返回;
设置状态(){
_hasreffintsupport=hasreffintsupport;
});
}
Future\u getAvailableSupport()异步{
List availableBuimetricType=List();
试一试{
可用的UIMetricType=
wait_localAuthentication.getAvailableByMetrics();
}捕获(e){
印刷品(e);
}
如果(!已安装)返回;
设置状态(){
_availableBuimetricType=availableBuimetricType;
});
}
Future\u authenticateMe()异步{
bool=false;
试一试{
已验证=等待_localAuthentication.authenticateWithBiometrics(
localizedReason:“使用应用程序进行身份验证”,//对话框消息
useErrorDialogs:true,//在对话框中显示错误
stickyAuth:false,//本机进程
);
}捕获(e){
印刷品(e);
}
如果(!已安装)返回;
设置状态(){
_authorizedOrNot=authorized?真:假;
});
}
@凌驾
小部件构建(构建上下文){
final themeNotifier=Provider.of(上下文);
_authenticateMe();
回程多供应商(
供应商:[
变更通知提供者(
创建:()=>ThemeNotifier(暗色),
),
ChangeNotifierProvider(创建:(\u)=>ImageUploadProvider()),
变更通知提供者(
创建:()=>VideoUploadProvider(),
),
ChangeNotifierProvider(创建:(\u)=>UserProvider()),
],
孩子:MaterialApp(
标题:“应用程序”,
debugShowCheckedModeBanner:false,
initialRoute:“/”,
路线:{
“/search_screen”:(上下文)=>SearchScreen(),
“/setting_page”:(上下文)=>settingPage(),
},
主题:themeNotifier.getTheme(),
家:未来建设者(
未来:_authMethods.getCurrentUser(),
生成器:(上下文,异步快照){
if(snapshot.hasData){
返回_authorizedOrNot==true?主屏幕():容器();
}否则{
返回LoginScreen();
}
},
),
),
);
}
}

在这种情况下,您可以调用
\u authenticateMe()在生成()的开始处

\u authenticateMe()
内部有一个setState,该setState会导致build()再次刷新并调用
\u authenticateMe()如此重建如此重建


另外,我会将FutureBuilder向上移动,直到超过MaterialApp,这可能会导致热重新加载的使用出现问题。

我找到了一种解决方法,在init状态下调用authenticate函数,然后在返回FutureBuilder之前检查isauthorizedorNot。 代码如下:-

class _MyAppState extends State<MyApp> {
final LocalAuthentication _localAuthentication = LocalAuthentication();
    final AuthMethods _authMethods = AuthMethods();
  bool _authorizedOrNot ;

  Future<void> _authenticateMe() async {
    bool authenticated = false;
    try {
      authenticated = await _localAuthentication.authenticateWithBiometrics(
        localizedReason: "Authenticate to use app", 
        useErrorDialogs: true,

        stickyAuth: false, 
      );
    } catch (e) {
      print(e);
    }
    if (!mounted) return;
    setState(() {
      _authorizedOrNot = authenticated ? true : false;
    });
  }

  @override
  void initState() {
   
    super.initState();
    _authenticateMe();
  }
  @override
  Widget build(BuildContext context) {
 
    final themeNotifier = Provider.of<ThemeNotifier>(context);
    
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (_) => ThemeNotifier(darkTheme),
        ),
        ChangeNotifierProvider(create: (_) => ImageUploadProvider()),
        ChangeNotifierProvider(
          create: (_) => VideoUploadProvider(),
        ),
        ChangeNotifierProvider(create: (_) => UserProvider()),
      ],
      child: MaterialApp(
        title: "App",
        debugShowCheckedModeBanner: false,
        initialRoute: '/',
        routes: {
          '/search_screen': (context) => SearchScreen(),
          '/setting_page': (context) => settingPage(),
        },
        theme: themeNotifier.getTheme(),
        home: _authorizedOrNot==true ?  FutureBuilder(
          future: _authMethods.getCurrentUser(),
          builder: (context, AsyncSnapshot<User> snapshot) {
 
            if (snapshot.hasData) {
              return HomeScreen();
             
            } else {
              return LoginScreen();
            
            }
          },
        )  : ( Container(child: Center(child: CircularProgressIndicator()),)
      ),)
    );
  }
}
class\u MyAppState扩展状态{
最终本地身份验证_LocalAuthentication=LocalAuthentication();
最终AuthMethods_AuthMethods=AuthMethods();
布尔多诺;
Future\u authenticateMe()异步{
bool=false;
试一试{
已验证=等待_localAuthentication.authenticateWithBiometrics(
localizedReason:“通过身份验证使用应用程序”,
useErrorDialogs:true,
stickyAuth:false,
);
}捕获(e){
印刷品(e);
}
如果(!已安装)返回;
设置状态(){
_authorizedOrNot=authorized?真:假;
});
}
@凌驾
void initState(){
super.initState();
_authenticateMe();
}
@凌驾
小部件构建(构建上下文){
final themeNotifier=Provider.of(上下文);
回程多供应商(
供应商:[
变更通知提供者(
创建:()=>ThemeNotifier(暗色),
),
ChangeNotifierProvider(创建:(\u)=>ImageUploadProvider()),
变更通知提供者(
创建:()=>VideoUploadProvider(),
),
ChangeNotifierProvider(创建:(\u)=>UserProvider()),
],
孩子:MaterialApp(
标题:“应用程序”,
debugShowCheckedModeBanner:false,
initialRoute:“/”,
路线:{
“/search_screen”:(上下文)=>SearchScreen(),
“/setting_page”:(上下文)=>settingPage(),
},
主题:themeNotifier.getTheme(),
主页:_authorizedOrNot==true?FutureBuilder(
class _MyAppState extends State<MyApp> {
final LocalAuthentication _localAuthentication = LocalAuthentication();
    final AuthMethods _authMethods = AuthMethods();
  bool _authorizedOrNot ;

  Future<void> _authenticateMe() async {
    bool authenticated = false;
    try {
      authenticated = await _localAuthentication.authenticateWithBiometrics(
        localizedReason: "Authenticate to use app", 
        useErrorDialogs: true,

        stickyAuth: false, 
      );
    } catch (e) {
      print(e);
    }
    if (!mounted) return;
    setState(() {
      _authorizedOrNot = authenticated ? true : false;
    });
  }

  @override
  void initState() {
   
    super.initState();
    _authenticateMe();
  }
  @override
  Widget build(BuildContext context) {
 
    final themeNotifier = Provider.of<ThemeNotifier>(context);
    
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (_) => ThemeNotifier(darkTheme),
        ),
        ChangeNotifierProvider(create: (_) => ImageUploadProvider()),
        ChangeNotifierProvider(
          create: (_) => VideoUploadProvider(),
        ),
        ChangeNotifierProvider(create: (_) => UserProvider()),
      ],
      child: MaterialApp(
        title: "App",
        debugShowCheckedModeBanner: false,
        initialRoute: '/',
        routes: {
          '/search_screen': (context) => SearchScreen(),
          '/setting_page': (context) => settingPage(),
        },
        theme: themeNotifier.getTheme(),
        home: _authorizedOrNot==true ?  FutureBuilder(
          future: _authMethods.getCurrentUser(),
          builder: (context, AsyncSnapshot<User> snapshot) {
 
            if (snapshot.hasData) {
              return HomeScreen();
             
            } else {
              return LoginScreen();
            
            }
          },
        )  : ( Container(child: Center(child: CircularProgressIndicator()),)
      ),)
    );
  }
}