Flutter 如何管理Flatter中的Firebase身份验证状态?

Flutter 如何管理Flatter中的Firebase身份验证状态?,flutter,dart,firebase-authentication,Flutter,Dart,Firebase Authentication,我有一个WelcomeScreen,其中包含注册和登录以及主屏幕,在用户登录后,我想在那里重定向。为了管理身份验证数据,我创建了一个带有static属性和方法的auth.dart,这样我就可以使用相同的数据跨所有页面访问它们 import'package:firebase_auth/firebase_auth.dart'; 类身份验证{ 静态最终身份验证=FirebaseAuth.instance; 静态未来注销()异步{ 等待auth.signOut(); } 静态未来登录用户(字符串用户电子

我有一个
WelcomeScreen
,其中包含注册和登录以及
主屏幕,在用户登录后,我想在那里重定向。为了管理身份验证数据,我创建了一个带有
static
属性和方法的
auth.dart
,这样我就可以使用相同的数据跨所有页面访问它们

import'package:firebase_auth/firebase_auth.dart';
类身份验证{
静态最终身份验证=FirebaseAuth.instance;
静态未来注销()异步{
等待auth.signOut();
}
静态未来登录用户(字符串用户电子邮件、字符串用户密码)异步{
使用email和password(电子邮件:userEmail,密码:userPassword)等待身份验证登录;
}
静态未来getCurrentUser()异步{
返回wait auth.currentUser();
}
}
main.dart
文件中,我正在使用
StreamBuilder
根据更改的身份验证数据更改当前屏幕。我从中获得了这个
StreamBuilder
代码

home:StreamBuilder(
流:Auth.Auth.onAuthStateChanged,
生成器:(上下文,快照){
if(snapshot.hasData){
返回主屏幕();
}否则{
返回WelcomeScreen();
}
},
),
在我的登录屏幕中,我使用以下代码触发登录:

Future login()异步{
...
试一试{
等待Auth.loginUser(用户电子邮件、用户密码);
var user=await Auth.getCurrentUser();
print(user.displayName);//这很有效
}捕获(错误){
打印(错误消息);
}
}
我不知道我使用的静态方法是否是处理Firebase auth的正确方法,但它似乎可以工作。登录后,我可以显示登录用户的姓名,但
main.dart
中的
StreamBuilder
没有反映更新的身份验证数据,即没有更改页面


这是因为静态方法还是StreamBuilder实现中的某些错误?

在我看来,在Flatter中管理firebase身份验证的最佳方法是使用提供程序包。您的Auth类缺少一个重要的东西,即onAuthStateChnaged方法。您可以创建一个流作为Auth类内onAuthStateChanged的getter。Auth类将扩展ChangeNotifier类。ChangeNotifier类是颤振api的一部分

class Auth extends ChangeNotifier {

    final FirebaseAuth _auth = FirebaseAuth.instance;

    // create a getter stream
    Stream<FirebaseUser> get onAuthStateChanged => _auth.onAuthStateChanged;

    //Sign in async functions here ..

}
现在将登录页创建为无状态小部件。使用使用者或提供者.of(上下文)和流生成器侦听身份验证更改,并根据需要呈现登录页面或主页

class Landing extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    Auth auth = Provider.of<Auth>(context);
    return StreamBuilder<FirebaseUser>(
      stream: auth.onAuthStateChanged,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.active) {
          FirebaseUser user = snapshot.data;
          if (user == null) {
            return LogIn();
          }
          return Home();
        } else {
          return Scaffold(
            body: Center(
              child: CircularProgressIndicator(),
            ),
          );
        }
      },
    );
  }
}
类登录扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){

Auth Auth=Provider.of

屏幕截图:

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MaterialApp(home: MyApp()));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder<FirebaseUser>(
      stream: Auth.auth.onAuthStateChanged,
      builder: (context, snapshot) {
        if (snapshot.hasData) return HomeScreen();
         else return WelcomeScreen();
      },
    );
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home Screen')),
      floatingActionButton: FloatingActionButton.extended(
        label: Text('Sign out'),
        onPressed: Auth.logout,
      ),
    );
  }
}

class WelcomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Welcome Screen')),
      body: Center(
        child: RaisedButton(
          onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (_) => LoginPage())),
          child: Text('Go to Login Page'),
        ),
      ),
    );
  }
}

class LoginPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Login Page')),
      body: Center(
        child: RaisedButton(
          onPressed: () async {
            await Auth.loginUser('test@test.com', 'test1234');
            await Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (_) => MyApp()), (_) => false);
          },
          child: Text('Login'),
        ),
      ),
    );
  }
}


我不知道你是怎么做的,所以我添加了一个最小的工作代码,我没有对你的
Auth
类做任何更改。虽然使用
Provider
是一个好主意,但是你也可以使用
静态
方法完成事情

编辑的代码:

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MaterialApp(home: MyApp()));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder<FirebaseUser>(
      stream: Auth.auth.onAuthStateChanged,
      builder: (context, snapshot) {
        if (snapshot.hasData) return HomeScreen();
         else return WelcomeScreen();
      },
    );
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home Screen')),
      floatingActionButton: FloatingActionButton.extended(
        label: Text('Sign out'),
        onPressed: Auth.logout,
      ),
    );
  }
}

class WelcomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Welcome Screen')),
      body: Center(
        child: RaisedButton(
          onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (_) => LoginPage())),
          child: Text('Go to Login Page'),
        ),
      ),
    );
  }
}

class LoginPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Login Page')),
      body: Center(
        child: RaisedButton(
          onPressed: () async {
            await Auth.loginUser('test@test.com', 'test1234');
            await Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (_) => MyApp()), (_) => false);
          },
          child: Text('Login'),
        ),
      ),
    );
  }
}
void main(){
WidgetsFlutterBinding.ensureInitialized();
runApp(MaterialApp(home:MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回流生成器(
流:Auth.Auth.onAuthStateChanged,
生成器:(上下文,快照){
if(snapshot.hasData)返回主屏幕();
否则返回WelcomeScreen();
},
);
}
}
类主屏幕扩展无状态小部件{
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(标题:文本(“主屏幕”),
floatingActionButton:floatingActionButton.extended(
标签:文本(“注销”),
onPressed:Auth.logout,
),
);
}
}
类WelcomeScreen扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(标题:文本(“欢迎屏幕”),
正文:中(
孩子:升起按钮(
onPressed:()=>Navigator.push(上下文,materialpage(生成器:()=>LoginPage()),
子项:文本(“转到登录页”),
),
),
);
}
}
类LoginPage扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(标题:文本(“登录页”),
正文:中(
孩子:升起按钮(
onPressed:()异步{
等待身份验证登录用户('test@test.com","test1234",;
等待Navigator.pushandremoveintil(上下文,materialpage路径(builder:()=>MyApp()),()=>false);
},
子项:文本('Login'),
),
),
);
}
}
Null安全代码(使用)


完整代码:

void main()异步{
WidgetsFlutterBinding.ensureInitialized();
等待Firebase.initializeApp();
runApp(
变更通知提供者(
创建:()=>AuthModel(),
孩子:MaterialApp(
家庭:消费者(
生成器:(u,auth,uu)=>auth.isSignedIn?主页():WelcomePage(),
),
),
),
);
}
类WelcomePage扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(标题:文本('WelcomePage')),
正文:中(
儿童:升降按钮(
onPressed:()=>Navigator.push(上下文,materialpage(生成器:()=>LoginPage()),
子项:文本(“转到登录页”),
),
),
);
}
}
类LoginPage扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(标题:文本(“登录页”),
正文:中(
儿童:升降按钮(
onPressed:()异步{
最终模型=context.read();
等待模型签名(电子邮件:'test@test.com,密码为:“test1234”);
Navigator.pop(上下文);
},
子项:文本('Login'),
),
),
);
}
}
类主页扩展了Widge