Flutter 使用Firebase的声明性身份验证路由
当用户登录或注销时,我使用流来监听登录和注销事件,而不是使用Flutter 使用Firebase的声明性身份验证路由,flutter,Flutter,当用户登录或注销时,我使用流来监听登录和注销事件,而不是使用Navigator.push推送用户 StreamProvider.value( 值:FirebaseAuth.instance.onAuthStateChanged, ) 它对home route非常有用,因为如果用户仍然经过身份验证,它会立即处理登录 消费者( 生成器:(uu,用户,uu){ final isLoggedIn=user!=null; 返回材料PP( 主页:isLoggedIn?主页():AuthPage(), //
Navigator.push推送用户
StreamProvider.value(
值:FirebaseAuth.instance.onAuthStateChanged,
)
它对home route非常有用,因为如果用户仍然经过身份验证,它会立即处理登录
消费者(
生成器:(uu,用户,uu){
final isLoggedIn=user!=null;
返回材料PP(
主页:isLoggedIn?主页():AuthPage(),
// ...
);
},
);
然而,这只是回家的路线。例如,如果用户随后导航到一个设置页面,在该页面中单击一个按钮进行注销,则不会有程序性的注销和再次跳转到auth屏幕。我要么说Navigator.of(context).pushName和removeUntil('/auth',(\u)=>false)
,要么得到一个关于user
为空的错误
这是有道理的。我只是在寻找另一种可能的方式,当他们注销时,我不必自己做任何堆栈管理
通过将builder
属性添加到MaterialApp
builder:(\uux,小部件){
返回isLoggedIn?小部件:AuthPage();
},
这在我未经身份验证后成功地将我移动到了auth页面,但事实证明,widget
实际上是导航器。这意味着当我返回到AuthPage
时,我无法调用任何依赖于父导航器的内容。这是怎么回事,你用这个小部件包装依赖于这个流的所有屏幕,它对你隐藏了监听流并相应更新的逻辑(你应该像你在问题中所做的那样提供流):
然后,您可以在从其他页面推送时使用它,如下所示:
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (ctx) => AuthDependentWidget(
childWidget: SettingsScreen(),//or any other screen that should listen to the stream
)));
我找到了一个方法来实现这一点(爱的伟大答案仍然是完全有效的),以防其他人在这个问题上采取行动:
您需要利用嵌套的导航器。Root
将是内部导航器,外部导航器由MaterialApp
创建:
return MaterialApp(
home:isLoggedIn?Root():AuthPage(),
路线:{
Root.routeName:()=>Root(),
AuthPage.routeName:(\u)=>AuthPage(),
},
);
您的根目录
将保留授权用户的导航
类根扩展StatefulWidget{
静态常量字符串routeName='/root';
@凌驾
_RootState createState()=>\u RootState();
}
类_RootState扩展了状态{
最终_appNavigatorKey=GlobalKey();
@凌驾
小部件构建(构建上下文){
返回式示波器(
onWillPop:()异步{
final canPop=_appNavigatorKey.currentState.canPop();
如果(canPop){
wait_appNavigatorKey.currentState.maybePop();
}
回来!坎普;
},
孩子:领航员(
initialRoute:HomePage.routeName,
OnGeneratorOute:(路由设置路由设置){
返回物料管理路线(生成器:(){
交换机(routeSettings.name){
案例首页.routeName:
返回主页();
关于page.routeName的案例:
返回约页();
案例术语UsePage.routeName:
返回TermsOfUsePage();
案例设置SPAGE.routeName:
返回设置spage();
案例EditorPage.routeName:
返回EditorPage();
违约:
抛出“未知路由${routeSettings.name}”;
}
});
},
),
);
}
}
现在,您可以在设置页面(或任何其他页面)内取消身份验证(FirebaseAuth.instance.signout()
)然后立即跳转到身份验证页面,而无需调用Navigator
方法。像第一个屏幕那样用Consumer
包装您的设置屏幕并不适合您?我的意思是在SettingPage.dart:isLoggedIn中类似的内容?SettingPage():AuthPage()
你好,亲爱的,这是一种方法,但我必须对每条路线都这样做不?假设我有一个关于页面或验证电子邮件页面,等等。谢谢爱,我现在肯定会用这个。我仍然很好奇,是否有一种方法可以在树的更高的位置进行导航,但我喜欢你的方法。刚刚经过这个,你能解释一下自动导航是如何进行的吗?请提供更多的代码
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (ctx) => AuthDependentWidget(
childWidget: SettingsScreen(),//or any other screen that should listen to the stream
)));