flutter 当用户关闭应用程序并返回时,用户如何保持登录?

klh5stk1  于 2023-06-30  发布在  Flutter
关注(0)|答案(2)|浏览(216)

“我正在创建一个基于角色的Flutter应用程序,其中的角色是病人,远程护理,顾问和管理员。我已经创建了登录页面,每个人都能够正确登录,但当您关闭应用程序并返回时,它不会保持用户登录,而是将您发送回登录屏幕,我如何解决这个问题?
这是我所尝试的;

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:telenursingapp/admin_portal.dart';
import 'package:telenursingapp/consultant_portal.dart';
import 'package:telenursingapp/patients_portal.dart';
import 'package:telenursingapp/telenurse_portal.dart';

class SignIn extends StatefulWidget {
  const SignIn({super.key});

  @override
  State<SignIn> createState() => _SignInState();
}

class _SignInState extends State<SignIn> {
  // text controllers
bool _isObscure3 = true;
  bool visible = false;
  final _formkey = GlobalKey<FormState>();
  final TextEditingController emailController = new TextEditingController();
  final TextEditingController passwordController = new TextEditingController();

  final _auth = FirebaseAuth.instance;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        child: Column(
          children: <Widget>[
            Container(
              decoration: BoxDecoration(
          gradient: LinearGradient(
              begin: Alignment.topRight,
              end: Alignment.bottomLeft,
              colors: [Colors.blueGrey, Color(0xFF3EB489)]),
        ),
              width: MediaQuery.of(context).size.width,
              height: MediaQuery.of(context).size.height * 1.0,
              child: Center(
                child: Container(
                  margin: EdgeInsets.all(12),
                  child: Form(
                    key: _formkey,
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        SizedBox(
                          height: 30,
                        ),
                      Image.asset('assets/YourDoc-black.png', width: 70),
                Icon(
                  FontAwesomeIcons.solidHandshake,
                  size: 20,
                  color: Colors.black,
                ),
              SizedBox(height: 80,),

                       Text('Login to your account!', 
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 44,
                        fontWeight: FontWeight.bold
                )),
                const SizedBox(height: 10,),
                const Text('Welcome back to YourDoc',
                style: TextStyle(
                  color: Color.fromARGB(255, 88, 85, 85),
                  fontSize: 24,)),
                        SizedBox(
                          height: 20,
                        ),
                        TextFormField(
                          controller: emailController,
                          decoration: InputDecoration(
                            filled: true,
                            fillColor: Colors.white,
                            hintText: 'Email',
                            enabled: true,
                            contentPadding: const EdgeInsets.only(
                                left: 14.0, bottom: 8.0, top: 8.0),
                            focusedBorder: OutlineInputBorder(
                              borderSide: new BorderSide(color: Colors.white),
                              borderRadius: new BorderRadius.circular(10),
                            ),
                            enabledBorder: UnderlineInputBorder(
                              borderSide: new BorderSide(color: Colors.white),
                              borderRadius: new BorderRadius.circular(10),
                            ),
                          ),
                          validator: (value) {
                            if (value!.length == 0) {
                              return "Email cannot be empty";
                            }
                            if (!RegExp(
                                    "^[a-zA-Z0-9+_.-]+@[a-zA-Z0-9.-]+.[a-z]")
                                .hasMatch(value)) {
                              return ("Please enter a valid email");
                            } else {
                              return null;
                            }
                          },
                          onSaved: (value) {
                            emailController.text = value!;
                          },
                          keyboardType: TextInputType.emailAddress,
                        ),
                        SizedBox(
                          height: 20,
                        ),
                        TextFormField(
                          controller: passwordController,
                          obscureText: _isObscure3,
                          decoration: InputDecoration(
                            suffixIcon: IconButton(
                                icon: Icon(_isObscure3
                                    ? Icons.visibility
                                    : Icons.visibility_off),
                                onPressed: () {
                                  setState(() {
                                    _isObscure3 = !_isObscure3;
                                  });
                                }),
                            filled: true,
                            fillColor: Colors.white,
                            hintText: 'Password',
                            enabled: true,
                            contentPadding: const EdgeInsets.only(
                                left: 14.0, bottom: 8.0, top: 15.0),
                            focusedBorder: OutlineInputBorder(
                              borderSide: new BorderSide(color: Colors.white),
                              borderRadius: new BorderRadius.circular(10),
                            ),
                            enabledBorder: UnderlineInputBorder(
                              borderSide: new BorderSide(color: Colors.white),
                              borderRadius: new BorderRadius.circular(10),
                            ),
                          ),
                          validator: (value) {
                            RegExp regex = new RegExp(r'^.{6,}$');
                            if (value!.isEmpty) {
                              return "Password cannot be empty";
                            }
                            if (!regex.hasMatch(value)) {
                              return ("please enter valid password min. 6 character");
                            } else {
                              return null;
                            }
                          },
                          onSaved: (value) {
                            passwordController.text = value!;
                          },
                          keyboardType: TextInputType.emailAddress,
                        ),
                       
                        SizedBox(
                          height: 20,
                        ),
                        MaterialButton(
                          shape: RoundedRectangleBorder(
                              borderRadius:
                                  BorderRadius.all(Radius.circular(20.0))),
                          elevation: 5.0,
                          height: 40,
                          minWidth: 500,
                          onPressed: () {
                            setState(() {
                              visible = true;
                            });
                            signIn(
                                emailController.text, passwordController.text);
                          },
                          color: Color.fromARGB(255, 20, 85, 206),
                          child: Text(
                            "Login",
                            style: TextStyle(
                              fontSize: 20,
                              fontWeight: FontWeight.bold,
                              color: Colors.white,

                            ),
                          ),
                        ),
                        SizedBox(
                          height: 10,
                        ),
                        Visibility(
                            maintainSize: true,
                            maintainAnimation: true,
                            maintainState: true,
                            visible: visible,
                            child: Container(
                                child: CircularProgressIndicator(
                              color: Colors.white,
                            ))),
                      ],
                    ),
                  ),
                ),
              ),
            ),
          
          ],
        ),
      ),
    );
  }

  void route() {
    User? user = FirebaseAuth.instance.currentUser;
    var kk = FirebaseFirestore.instance
            .collection('users')
            .doc(user!.uid)
            .get()
            .then((DocumentSnapshot documentSnapshot) {
      if (documentSnapshot.exists) {
        if (documentSnapshot.get('role') == "Patient") {
           Navigator.pushReplacement(
          context,
          MaterialPageRoute(
            builder: (context) =>  PatientsPortal(),
          ),
        );
        }
        else if(documentSnapshot.get('role') == "Consultant"){
          Navigator.pushReplacement(
          context, 
          MaterialPageRoute(builder: (context) => ConsultantPortal()));
        }
        else if(documentSnapshot.get('role') == "New Admin"){
          Navigator.pushReplacement(
          context, 
          MaterialPageRoute(builder: (context) => AdminPortal()));
        }
        else if(documentSnapshot.get('role') == "Telenurse"){
          Navigator.pushReplacement(
          context, 
          MaterialPageRoute(builder: (context) => TelenursePortal()));
        }
        else{
          Navigator.pushReplacement(
          context,
          MaterialPageRoute(
            builder: (context) =>  SignIn(),
          ),
        );
        }
      } else {
        print('Document does not exist on the database');
      }
    });
  }

  void signIn(String email, String password) async {
    if (_formkey.currentState!.validate()) {
      try {
        UserCredential userCredential =
            await FirebaseAuth.instance.signInWithEmailAndPassword(
          email: email,
          password: password,
        );
        route();
      } on FirebaseAuthException catch (e) {
        if (e.code == 'user-not-found') {
          print('No user found for that email.');
        } else if (e.code == 'wrong-password') {
          print('Wrong password provided for that user.');
        }
      }
    }
  }
}
hgqdbh6s

hgqdbh6s1#

您应该使用或Shared Preferences在本地存储一个名为isLoggedInUser的布尔变量,一旦用户登录,您可以将此变量设置为true,其默认值为false。
因此,发生的事情是,你可以检查启动屏幕,如果该标志是真的,那么你将重定向用户到 Jmeter 板,否则你可以重定向用户到登录屏幕。
您还可以存储其他变量,如用户类型和他们的id,以供在应用程序中进一步使用。这样用户就不需要每次打开应用程序时都登录。
这里有一个类,你可以用它在本地存储和获取变量。
import 'package:shared_preferences/shared_preferences. dart';

class MyPrefs {
  Future<void> setValue<T>(String key, T value) async {
    final prefs = await SharedPreferences.getInstance();

    if (value is int) {
      prefs.setInt(key, value);
    } else if (value is String) {
      prefs.setString(key, value);
    } else if (value is bool) {
      prefs.setBool(key, value);
    }
  }

  Future<T> getValue<T>(String key, T defaultValue) async {
    final prefs = await SharedPreferences.getInstance();

    if (defaultValue is String) {
      return (prefs.getString(key) ?? "") as T;
    } else if (defaultValue is int) {
      return (prefs.getInt(key) ?? 0) as T;
    } else {
      return (prefs.getBool(key) ?? false) as T;
    }
  }
}

这样使用:
集合:MyPrefs().setValue("isLoggedInUser", true/false);。<--这里需要传递true或false作为值
获取:await MyPrefs().getValue("isLoggedInUser", false);。<--这里false是默认值

dgenwo3n

dgenwo3n2#

Firebase Authentication SDK会自动将用户的凭据存储在本地存储中,并在应用重新启动时从本地存储中恢复这些凭据。
然而,这样做需要它调用服务器,检查凭证是否仍然有效,并确保用户没有被禁用,这需要时间。
在此检查期间,应用程序不会等待第一次渲染,而是在此过程中正常启动。这是第一次运行你的buildroute,(我猜,因为我在你分享的内容中没有看到这段代码)然后检查FirebaseAuth.instance.currentUser并注意到它是null,所以没有人登录(还没有)。
没有办法阻止这种行为。因此,您应该通过侦听authStateChanges()流来响应Firebase何时完成其恢复流程,如获取当前用户的文档的第一个示例所示:

FirebaseAuth.instance
  .authStateChanges()
  .listen((User? user) {
    if (user != null) {
      print(user.uid);
    }
  });

由于您可能会在UI中执行此操作,因此需要在其中使用StreamBuilder来 Package FirebaseAuth.instance.authStateChanges()

相关问题