Flatter/Firebase:动态主页,取决于使用多供应商问题的用户登录状态

Flatter/Firebase:动态主页,取决于使用多供应商问题的用户登录状态,firebase,flutter,dart,firebase-authentication,Firebase,Flutter,Dart,Firebase Authentication,我想检查用户是否已经登录,并根据情况向他显示页面 这是我的main.dart: ... import 'firebase/authentication_service.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); runApp(MyApp()); } class MyApp extends StatelessWidget {

我想检查用户是否已经登录,并根据情况向他显示页面

这是我的
main.dart

...
import 'firebase/authentication_service.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        Provider<AuthenticationService>(
          create: (_) => AuthenticationService(FirebaseAuth.instance),
        ),
        StreamProvider(
          create: (context) =>
              context.read<AuthenticationService>().authStateChanges,
          initialData: null,
        ),
      ],
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
            backgroundColor: Colors.transparent,
            primaryColor: Color(0xff4d629f),
            buttonBarTheme:
                ButtonBarThemeData(alignment: MainAxisAlignment.center)),
        home: AuthenticationWrapper(),
      ),
    );
  }
}

class AuthenticationWrapper extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final firebaseUser = context.watch<User>();

    if (firebaseUser != null) {
      //If the user is successfully Logged-In.
      return HomePage();
    } else {
      //If the user is not Logged-In.
      return LoginPage();
    }
  }
}

class AuthenticationService {
  final FirebaseAuth _firebaseAuth;
  UserModel userModel = UserModel.empty();
  final userRef = FirebaseFirestore.instance.collection('users');

  AuthenticationService(this._firebaseAuth);

  Stream<User?> get authStateChanges => _firebaseAuth.authStateChanges();

  Future<String> signIn(
      {required String email, required String password}) async {
    try {
      await _firebaseAuth.signInWithEmailAndPassword(
          email: email, password: password);
      return "Signed in";
    } on FirebaseAuthException catch (e) {
      if (e.code == 'user-not-found')
        return "There is no user for that e-mail";
      else if (e.code == 'wrong-password')
        return "Entered wrong Password";
      else
        return "Something went wrong: $e";
    }
  }
...
还有一些错误:

生成AuthenticationWrapper(脏)时引发了以下ProviderNotFoundException: 错误:在此AuthenticationWrapper小部件上方找不到正确的提供程序 这是因为您使用了不包含提供程序的
BuildContext
由你选择。有几个常见的场景:

  • 您在
    main.dart
    中添加了一个新的提供程序,并执行了热重新加载。 要修复此问题,请执行热重启
  • 您试图读取的提供程序位于不同的路径中
  • 提供者是“有范围的”。所以,如果在路由中插入一个提供者,那么 其他路由将无法访问该提供商
  • 您使用了一个
    BuildContext
    ,它是您试图读取的提供程序的祖先。 确保AuthenticationWrapper位于MultiProvider/Provider下。 这通常发生在创建提供者并尝试立即读取它时。 例如,而不是:

不幸的是,它没有帮助,或者我无法以正确的方式实现它。

@SumerSingh解决方案奏效了,我只是对它做了一些修改以供使用

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool _initialized = false;
  bool _error = false;
  void initializeFlutterFire() async {
    try {
      await Firebase.initializeApp();
      setState(() {
        _initialized = true;
      });
    } catch (e) {
      setState(() {
        _error = true;
      });
    }
  }

  @override
  void initState() {
    initializeFlutterFire();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'App',
        debugShowCheckedModeBanner: false,
        home: Scaffold(
            body: _error
                ? splashScreen()
                : !_initialized
                    ? splashScreen()
                    : SplashScreen()));
  }
}

class SplashScreen extends StatefulWidget {
  SplashScreen({Key? key}) : super(key: key);

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

class _SplashScreenState extends State<SplashScreen> {
  final FirebaseAuth _auth = FirebaseAuth.instance;
  var currentUser;
  AuthenticationService _authService =
      new AuthenticationService(FirebaseAuth.instance);
  late final UserModel userModel;
  bool isAuthinticated = false;

  _isUserSignedin() async {
    currentUser = _auth.currentUser;
    userModel = await _authService.getUserFromDB(uid: _auth.currentUser!.uid);
    setState(() {
      currentUser != null ? isAuthinticated = true : isAuthinticated = false;
    });
  }

  @override
  void initState() {
    super.initState();
    _isUserSignedin();
    startTime();
  }

  startTime() async {
    var _duration = new Duration(seconds: 4);
    return new Timer(_duration, navigationPage);
  }

  Widget userAuthState() {
    if (!isAuthinticated)
      return LoginPage();
    else if (userModel.type == 'Attendant')
      return AttendantMainPage();
    else
      return SeniorMainPage();
  }

  void navigationPage() {
    Navigator.pushReplacement(
      context,
      MaterialPageRoute(builder: (BuildContext context) => userAuthState()),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(body: splashScreen());
  }
}

Widget splashScreen() {
  return Container(
    height: double.maxFinite,
    width: double.maxFinite,
    child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisSize: MainAxisSize.max,
        children: [
          CircleAvatar(
              radius: 80.0, child: Image.asset('assets/logo.png')),
          Text("APP NAME",
              style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
          CircularProgressIndicator()
        ]),
  );
}

void main(){
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
类MyApp扩展了StatefulWidget{
@凌驾
_MyAppState createState()=>\u MyAppState();
}
类MyAppState扩展了状态{
bool _initialized=false;
布尔误差=假;
void initializeFlutterFire()异步{
试一试{
等待Firebase.initializeApp();
设置状态(){
_初始化=真;
});
}捕获(e){
设置状态(){
_错误=真;
});
}
}
@凌驾
void initState(){
初始化fLutterFire();
super.initState();
}
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“应用程序”,
debugShowCheckedModeBanner:false,
家:脚手架(
正文:\ u错误
?防溅屏()
:!\u已初始化
?防溅屏()
:SplashScreen());
}
}
类SplashScreen扩展StatefulWidget{
飞溅屏幕({Key?Key}):超级(Key:Key);
@凌驾
_SplashScreenState createState()=>\u SplashScreenState();
}
类的状态扩展了状态{
final FirebaseAuth _auth=FirebaseAuth.instance;
无功电流用户;
AuthenticationService\u authService=
新的AuthenticationService(FirebaseAuth.instance);
后期最终用户模型用户模型;
bool isAuthinticated=false;
_isUserSignedin()异步{
currentUser=_auth.currentUser;
userModel=await\u authService.getUserFromDB(uid:\u auth.currentUser!.uid);
设置状态(){
currentUser!=null?IsAuthInitiated=true:IsAuthInitiated=false;
});
}
@凌驾
void initState(){
super.initState();
_isUserSignedin();
开始时间();
}
startTime()异步{
var_持续时间=新的持续时间(秒:4);
返回新计时器(_持续时间,导航页面);
}
小部件userAuthState(){
如果(!IsAuthenticated)
返回登录页面();
else if(userModel.type=='Attendant')
返回AttendantMainPage();
其他的
返回主页();
}
无效导航页(){
导航器。更换(
上下文
MaterialPage路由(生成器:(BuildContext上下文)=>userAuthState()),
);
}
@凌驾
小部件构建(构建上下文){
返回脚手架(主体:防溅屏());
}
}
窗口小部件splashScreen(){
返回容器(
高度:double.maxFinite,
宽度:double.maxFinite,
子:列(
mainAxisAlignment:mainAxisAlignment.space,
crossAxisAlignment:crossAxisAlignment.center,
mainAxisSize:mainAxisSize.max,
儿童:[
圆形(
半径:80.0,子级:Image.asset('assets/logo.png'),
文本(“应用程序名称”,
样式:TextStyle(fontSize:20,fontWeight:fontWeight.bold)),
循环推进指示器()
]),
);
}

它工作得很好,谢谢你的帮助

firebase本身就是状态管理库。因此,在单个项目中使用两种状态管理是毫无意义的。你让你的生活变得艰难,那么如何以正确的方式让它变得艰难呢@SumerSingh将此代码复制到你的main.dart中并试用
Widget build(BuildContext context) {
  return Provider<Example>(
    create: (_) => Example(),
    // we use `builder` to obtain a new `BuildContext` that has access to the provider
    builder: (context) {
      // No longer throws
      return Text(context.watch<Example>()),
    }
  ),
}
void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool _initialized = false;
  bool _error = false;
  void initializeFlutterFire() async {
    try {
      await Firebase.initializeApp();
      setState(() {
        _initialized = true;
      });
    } catch (e) {
      setState(() {
        _error = true;
      });
    }
  }

  @override
  void initState() {
    initializeFlutterFire();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'App',
        debugShowCheckedModeBanner: false,
        home: Scaffold(
            body: _error
                ? splashScreen()
                : !_initialized
                    ? splashScreen()
                    : SplashScreen()));
  }
}

class SplashScreen extends StatefulWidget {
  SplashScreen({Key? key}) : super(key: key);

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

class _SplashScreenState extends State<SplashScreen> {
  final FirebaseAuth _auth = FirebaseAuth.instance;
  var currentUser;
  AuthenticationService _authService =
      new AuthenticationService(FirebaseAuth.instance);
  late final UserModel userModel;
  bool isAuthinticated = false;

  _isUserSignedin() async {
    currentUser = _auth.currentUser;
    userModel = await _authService.getUserFromDB(uid: _auth.currentUser!.uid);
    setState(() {
      currentUser != null ? isAuthinticated = true : isAuthinticated = false;
    });
  }

  @override
  void initState() {
    super.initState();
    _isUserSignedin();
    startTime();
  }

  startTime() async {
    var _duration = new Duration(seconds: 4);
    return new Timer(_duration, navigationPage);
  }

  Widget userAuthState() {
    if (!isAuthinticated)
      return LoginPage();
    else if (userModel.type == 'Attendant')
      return AttendantMainPage();
    else
      return SeniorMainPage();
  }

  void navigationPage() {
    Navigator.pushReplacement(
      context,
      MaterialPageRoute(builder: (BuildContext context) => userAuthState()),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(body: splashScreen());
  }
}

Widget splashScreen() {
  return Container(
    height: double.maxFinite,
    width: double.maxFinite,
    child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisSize: MainAxisSize.max,
        children: [
          CircleAvatar(
              radius: 80.0, child: Image.asset('assets/logo.png')),
          Text("APP NAME",
              style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
          CircularProgressIndicator()
        ]),
  );
}