使用Firebase进行声明式身份验证路由 [英] Declarative auth routing with Firebase

查看:66
本文介绍了使用Firebase进行声明式身份验证路由的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我没有使用 Navigator.push 来使用户登录或注销,而是一直使用流来侦听登录和注销事件.

Rather than pushing the user around with Navigator.push when they sign in or out, I've been using a stream to listen for sign in and sign out events.

StreamProvider<FirebaseUser>.value(
  value: FirebaseAuth.instance.onAuthStateChanged,
)

它对于本地路由非常有用,因为它可以立即处理仍在通过身份验证的用户登录.

It works great for the home route as it handles logging in users immediately if they're still authed.

Consumer<FirebaseUser>(
  builder: (_, user, __) {
    final isLoggedIn = user != null;

    return MaterialApp(
      home: isLoggedIn ? HomePage() : AuthPage(),
      // ...
    );
  },
);

但是,这仅适用于本国路线.例如,如果用户随后导航到设置页面,然后单击按钮以注销,则不会以编程方式注销并再次跳转到身份验证屏幕.我要么不得不说 Navigator.of(context).pushNamedAndRemoveUntil('/auth',(_)=>假),要么会得到关于 user 为空的错误.

However, that's just for the home route. For example, if the user then navigates to a settings page where they click a button to sign out, there's no programmatic logging out and kicking to the auth screen again. I either have to say Navigator.of(context).pushNamedAndRemoveUntil('/auth', (_) => false) or get an error about user being null.

这很有道理.我只是在寻找另一种可能的方式,当他们注销时,我自己不必进行任何堆栈管理.

This makes sense. I'm just looking for possibly another way that when they do get logged out I don't have to do any stack management myself.

通过将 builder 属性添加到 MaterialApp

builder: (_, widget) {
  return isLoggedIn ? widget : AuthPage();
},

这使我在未经身份验证后成功地将我移动到身份验证页面,但事实证明, widget 实际上是导航器.这意味着当我回到 AuthPage 时,我无法调用依赖于父级导航器的任何内容.

This successfully moved me to the auth page after I was unauthenticated but as it turns out, widget is actually the Navigator. And that means when I went back to AuthPage I couldn't call anything that relied on a parent Navigator.

推荐答案

我找到了一种方法来完成此任务(LoVe的最佳答案仍然完全有效),以防其他任何人涉足此问题:

I found a way to accomplish this (LoVe's great answer is still completely valid) in case anyone else steps on this issue:

您需要利用嵌套的导航器. Root 将是内部导航器,外部导航器由 MaterialApp 创建:

You'll need to take advantage of nested navigators. The Root will be the inner navigator and the outer navigator is created by MaterialApp:

return MaterialApp(
  home: isLoggedIn ? Root() : AuthPage(),
  routes: {
    Root.routeName: (_) => Root(),
    AuthPage.routeName: (_) => AuthPage(),
  },
);

您的 Root 将保存已认证用户的导航

Your Root will hold the navigation for an authed user

class Root extends StatefulWidget {
  static const String routeName = '/root';

  @override
  _RootState createState() => _RootState();
}

class _RootState extends State<Root> {
  final _appNavigatorKey = GlobalKey<NavigatorState>();
  
  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        final canPop = _appNavigatorKey.currentState.canPop();

        if (canPop) {
          await _appNavigatorKey.currentState.maybePop();
        }

        return !canPop;
      },
      child: Navigator(
        initialRoute: HomePage.routeName,
        onGenerateRoute: (RouteSettings routeSettings) {
          return MaterialPageRoute(builder: (_) {
            switch (routeSettings.name) {
              case HomePage.routeName:
                return HomePage();
              case AboutPage.routeName:
                return AboutPage();
              case TermsOfUsePage.routeName:
                return TermsOfUsePage();
              case SettingsPage.routeName:
                return SettingsPage();
              case EditorPage.routeName:
                return EditorPage();
              default:
                throw 'Unknown route ${routeSettings.name}';
            }
          });
        },
      ),
    );
  }
}

现在,您可以在设置页面(或任何其他页面)内取消身份验证( FirebaseAuth.instance.signout()),然后立即被踢出auth页面,而无需调用 Navigator方法.

Now you can unauthenticate (FirebaseAuth.instance.signout()) inside of the settings page (or any other page) and immediately get kicked out to the auth page without calling a Navigator method.

这篇关于使用Firebase进行声明式身份验证路由的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆