扑面应用程序保存用户身份验证状态所需的帮助

发布于 2025-02-12 11:00:28 字数 9411 浏览 0 评论 0原文

我有一个应用程序,用户当前可以登录(使用电话auth)并从主屏幕登录。但是,每当应用程序刷新时,用户就会自动登录。 我要做的是保持用户登录,直到他按下注销按钮为止。

由于我是新手的颤抖和编码,如果您可以为我提供确切的代码,那将是有帮助的。

main.dart

import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';

import 'login.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  Firebase.initializeApp();
  runApp(const MaterialApp(
    home: MyApp(),
    debugShowCheckedModeBanner: false,
  ));
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return const LoginScreen();
  }
}

login.dart

import 'package:flutter/material.dart';
import 'otp.dart';
import 'package:intl_phone_field/intl_phone_field.dart';

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

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

class _LoginScreenState extends State<LoginScreen> {
  String Country = '';
  final TextEditingController _controller2 = TextEditingController();

  final TextEditingController _controller = TextEditingController();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Phone Auth'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Column(children: [
            Container(
              margin: const EdgeInsets.only(top: 60),
              child: const Center(
                child: Text(
                  'Phone Authentication',
                  style: TextStyle(fontWeight: FontWeight.bold, fontSize: 28),
                ),
              ),
            ),

            //Phone feild

            IntlPhoneField(
              decoration: const InputDecoration(
                labelText: 'Phone Number',
                border: OutlineInputBorder(
                  borderSide: BorderSide(),
                ),
              ),
              controller: _controller,
              initialCountryCode: 'IN',
              onChanged: (phone) {
                debugPrint('Below is phone number');
                debugPrint(phone.completeNumber);
                debugPrint('Country code is: ${phone.countryCode}');
                Country = phone.countryCode;
                // phone.countryCode = _controller2 as String;
                debugPrint(Country);
              },
            ),
            // Container(
            //   margin: const EdgeInsets.only(top: 40, right: 10, left: 10),
            //   child: TextField(
            //     decoration: const InputDecoration(
            //       hintText: 'Phone Number',
            //       prefix: Padding(
            //         padding: EdgeInsets.all(4),
            //         child: Text('+91'),
            //       ),
            //     ),
            //     maxLength: 10,
            //     keyboardType: TextInputType.number,
            //     controller: _controller,
            //   ),
            // )
          ]),
          Container(
            margin: const EdgeInsets.all(10),
            width: double.infinity,
            child: FlatButton(
              color: Colors.blue,
              onPressed: () {
                Navigator.of(context).push(MaterialPageRoute(
                    builder: (context) =>
                        OTPScreen(_controller.text, Country)));
              },
              child: const Text(
                'Next',
                style: TextStyle(color: Colors.white),
              ),
            ),
          )
        ],
      ),
    );
  }
}

otp.dart

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'home.dart';
import 'package:pinput/pinput.dart';

class OTPScreen extends StatefulWidget {
  final String phone;
  final String countryCode;
  const OTPScreen(this.phone, this.countryCode, {Key? key}) : super(key: key);
  @override
  _OTPScreenState createState() => _OTPScreenState();
}

class _OTPScreenState extends State<OTPScreen> {
  final GlobalKey<ScaffoldState> _scaffoldkey = GlobalKey<ScaffoldState>();
  late String _verificationCode;
  final TextEditingController _pinPutController = TextEditingController();
  final FocusNode _pinPutFocusNode = FocusNode();
  final BoxDecoration pinPutDecoration = BoxDecoration(
    color: const Color.fromRGBO(43, 46, 66, 1),
    borderRadius: BorderRadius.circular(10.0),
    border: Border.all(
      color: const Color.fromRGBO(126, 203, 224, 1),
    ),
  );
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldkey,
      appBar: AppBar(
        title: const Text('OTP Verification'),
      ),
      body: Column(
        children: [
          Container(
            margin: const EdgeInsets.only(top: 40),
            child: Center(
              child: Text(
                'Verify ${widget.countryCode} ${widget.phone}',
                style:
                    const TextStyle(fontWeight: FontWeight.bold, fontSize: 26),
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(30.0),
            child: Pinput(
              length: 6,
              // fieldsCount: 6,
              // textStyle: const TextStyle(fontSize: 25.0, color: Colors.white),
              // eachFieldWidth: 40.0,
              // eachFieldHeight: 55.0,
              // focusNode: _pinPutFocusNode,
              // controller: _pinPutController,
              // submittedFieldDecoration: pinPutDecoration,
              // selectedFieldDecoration: pinPutDecoration,
              // followingFieldDecoration: pinPutDecoration,
              // pinAnimationType: PinAnimationType.fade,
              onSubmitted: (pin) async {
                debugPrint('submit pressed');

                try {
                  await FirebaseAuth.instance
                      .signInWithCredential(PhoneAuthProvider.credential(
                          verificationId: _verificationCode, smsCode: pin))
                      .then((value) async {
                    if (value.user != null) {
                      Navigator.pushAndRemoveUntil(
                          context,
                          MaterialPageRoute(builder: (context) => Home()),
                          (route) => false);
                    }
                  });
                } catch (e) {
                  FocusScope.of(context).unfocus();
                  _scaffoldkey.currentState!.showSnackBar(
                      const SnackBar(content: Text('invalid OTP')));
                }
              },
            ),
          )
        ],
      ),
    );
  }

  _verifyPhone() async {
    await FirebaseAuth.instance.verifyPhoneNumber(
        phoneNumber: '${widget.countryCode}${widget.phone}',
        verificationCompleted: (PhoneAuthCredential credential) async {
          await FirebaseAuth.instance
              .signInWithCredential(credential)
              .then((value) async {
            if (value.user != null) {
              Navigator.pushAndRemoveUntil(
                  context,
                  MaterialPageRoute(builder: (context) => Home()),
                  (route) => false);
            }
          });
        },
        verificationFailed: (FirebaseAuthException e) {
          debugPrint(e.message);
        },
        codeSent: (String verficationID, int? resendToken) {
          setState(() {
            _verificationCode = verficationID;
          });
        },
        codeAutoRetrievalTimeout: (String verificationID) {
          setState(() {
            _verificationCode = verificationID;
          });
        },
        timeout: const Duration(seconds: 120));
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _verifyPhone();
  }
}

home.dart

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'login.dart';

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

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

class _HomeState extends State<Home> {
  late String uid;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
        actions: [
          IconButton(
            icon: const Icon(Icons.logout),
            onPressed: () async {
              await FirebaseAuth.instance.signOut();
              Navigator.pushAndRemoveUntil(
                  context,
                  MaterialPageRoute(builder: (context) => const LoginScreen()),
                  (route) => false);
            },
          )
        ],
      ),
      body: Center(
        child: Text(uid),
      ),
    );
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    uid = FirebaseAuth.instance.currentUser!.uid;
  }
}

I have an app where Users can currently log in (using phone auth) and log out from the home screen. But whenever the app gets refreshed the user logs out automatically.
What I want to do is to keep the user logged in till he pressed the log out button.

Since I am new to flutter and coding in general it would be helpful if you can help me with the exact code.
enter image description here

main.dart

import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';

import 'login.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  Firebase.initializeApp();
  runApp(const MaterialApp(
    home: MyApp(),
    debugShowCheckedModeBanner: false,
  ));
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return const LoginScreen();
  }
}

login.dart

import 'package:flutter/material.dart';
import 'otp.dart';
import 'package:intl_phone_field/intl_phone_field.dart';

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

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

class _LoginScreenState extends State<LoginScreen> {
  String Country = '';
  final TextEditingController _controller2 = TextEditingController();

  final TextEditingController _controller = TextEditingController();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Phone Auth'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Column(children: [
            Container(
              margin: const EdgeInsets.only(top: 60),
              child: const Center(
                child: Text(
                  'Phone Authentication',
                  style: TextStyle(fontWeight: FontWeight.bold, fontSize: 28),
                ),
              ),
            ),

            //Phone feild

            IntlPhoneField(
              decoration: const InputDecoration(
                labelText: 'Phone Number',
                border: OutlineInputBorder(
                  borderSide: BorderSide(),
                ),
              ),
              controller: _controller,
              initialCountryCode: 'IN',
              onChanged: (phone) {
                debugPrint('Below is phone number');
                debugPrint(phone.completeNumber);
                debugPrint('Country code is: ${phone.countryCode}');
                Country = phone.countryCode;
                // phone.countryCode = _controller2 as String;
                debugPrint(Country);
              },
            ),
            // Container(
            //   margin: const EdgeInsets.only(top: 40, right: 10, left: 10),
            //   child: TextField(
            //     decoration: const InputDecoration(
            //       hintText: 'Phone Number',
            //       prefix: Padding(
            //         padding: EdgeInsets.all(4),
            //         child: Text('+91'),
            //       ),
            //     ),
            //     maxLength: 10,
            //     keyboardType: TextInputType.number,
            //     controller: _controller,
            //   ),
            // )
          ]),
          Container(
            margin: const EdgeInsets.all(10),
            width: double.infinity,
            child: FlatButton(
              color: Colors.blue,
              onPressed: () {
                Navigator.of(context).push(MaterialPageRoute(
                    builder: (context) =>
                        OTPScreen(_controller.text, Country)));
              },
              child: const Text(
                'Next',
                style: TextStyle(color: Colors.white),
              ),
            ),
          )
        ],
      ),
    );
  }
}

otp.dart

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'home.dart';
import 'package:pinput/pinput.dart';

class OTPScreen extends StatefulWidget {
  final String phone;
  final String countryCode;
  const OTPScreen(this.phone, this.countryCode, {Key? key}) : super(key: key);
  @override
  _OTPScreenState createState() => _OTPScreenState();
}

class _OTPScreenState extends State<OTPScreen> {
  final GlobalKey<ScaffoldState> _scaffoldkey = GlobalKey<ScaffoldState>();
  late String _verificationCode;
  final TextEditingController _pinPutController = TextEditingController();
  final FocusNode _pinPutFocusNode = FocusNode();
  final BoxDecoration pinPutDecoration = BoxDecoration(
    color: const Color.fromRGBO(43, 46, 66, 1),
    borderRadius: BorderRadius.circular(10.0),
    border: Border.all(
      color: const Color.fromRGBO(126, 203, 224, 1),
    ),
  );
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldkey,
      appBar: AppBar(
        title: const Text('OTP Verification'),
      ),
      body: Column(
        children: [
          Container(
            margin: const EdgeInsets.only(top: 40),
            child: Center(
              child: Text(
                'Verify ${widget.countryCode} ${widget.phone}',
                style:
                    const TextStyle(fontWeight: FontWeight.bold, fontSize: 26),
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(30.0),
            child: Pinput(
              length: 6,
              // fieldsCount: 6,
              // textStyle: const TextStyle(fontSize: 25.0, color: Colors.white),
              // eachFieldWidth: 40.0,
              // eachFieldHeight: 55.0,
              // focusNode: _pinPutFocusNode,
              // controller: _pinPutController,
              // submittedFieldDecoration: pinPutDecoration,
              // selectedFieldDecoration: pinPutDecoration,
              // followingFieldDecoration: pinPutDecoration,
              // pinAnimationType: PinAnimationType.fade,
              onSubmitted: (pin) async {
                debugPrint('submit pressed');

                try {
                  await FirebaseAuth.instance
                      .signInWithCredential(PhoneAuthProvider.credential(
                          verificationId: _verificationCode, smsCode: pin))
                      .then((value) async {
                    if (value.user != null) {
                      Navigator.pushAndRemoveUntil(
                          context,
                          MaterialPageRoute(builder: (context) => Home()),
                          (route) => false);
                    }
                  });
                } catch (e) {
                  FocusScope.of(context).unfocus();
                  _scaffoldkey.currentState!.showSnackBar(
                      const SnackBar(content: Text('invalid OTP')));
                }
              },
            ),
          )
        ],
      ),
    );
  }

  _verifyPhone() async {
    await FirebaseAuth.instance.verifyPhoneNumber(
        phoneNumber: '${widget.countryCode}${widget.phone}',
        verificationCompleted: (PhoneAuthCredential credential) async {
          await FirebaseAuth.instance
              .signInWithCredential(credential)
              .then((value) async {
            if (value.user != null) {
              Navigator.pushAndRemoveUntil(
                  context,
                  MaterialPageRoute(builder: (context) => Home()),
                  (route) => false);
            }
          });
        },
        verificationFailed: (FirebaseAuthException e) {
          debugPrint(e.message);
        },
        codeSent: (String verficationID, int? resendToken) {
          setState(() {
            _verificationCode = verficationID;
          });
        },
        codeAutoRetrievalTimeout: (String verificationID) {
          setState(() {
            _verificationCode = verificationID;
          });
        },
        timeout: const Duration(seconds: 120));
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _verifyPhone();
  }
}

home.dart

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'login.dart';

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

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

class _HomeState extends State<Home> {
  late String uid;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
        actions: [
          IconButton(
            icon: const Icon(Icons.logout),
            onPressed: () async {
              await FirebaseAuth.instance.signOut();
              Navigator.pushAndRemoveUntil(
                  context,
                  MaterialPageRoute(builder: (context) => const LoginScreen()),
                  (route) => false);
            },
          )
        ],
      ),
      body: Center(
        child: Text(uid),
      ),
    );
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    uid = FirebaseAuth.instance.currentUser!.uid;
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

今天小雨转甜 2025-02-19 11:00:29

一种完美的方法是将数据存储在共享的偏好中。您需要添加flutter_preference软件包[https://pub.dev/packages/shared_preferences]。

添加此软件包后的配置

  1. ,创建一个共享_preference对象,例如: *最终偏好=等待sharedPreference.getInstance *
  2. 接下来,您可以使用偏好对象在移动存储上存储日志。例如,要存储用户的变量术语(将身份验证存储为bool)状态,请执行以下操作
  3. : 。
    首先在第一步(1)中创建另一个偏好对象loke。但是这次而不是setBool,请使用getBool,例如:* final isalReadyAuthenticatiCation = persences.getBool(“ authentication”)*
  4. 现在,isaleadyauthenticatienationed符合该值是否已登录,您是否可以使用它来显示该值的登录屏幕是错误的

One perfect way is to store the data in shared preferences. All you need in to add the flutter shared_preference package [https://pub.dev/packages/shared_preferences].

CONFIGURATION

  1. After adding this package, create a shared_preference object like: * final preference = await SharedPreference.getInstance*
  2. Next you can store the logs on the mobile storage using the preference object. For example, to store a variable isAuthenticated(which stores the authentication as bool) status of the user, do something like: * await preference.setBool("authentication", isAuthenticated)*
  3. Step three, create another method to retrieve the data from storage.
    first create another preference object loke in step one(1). But this time instead of setBool, use getBool like:* final isAlreadyAuthenticated = preferences.getBool("authentication")*
  4. Now isAleadyAuthenticated holds the value whether is user already login or not and can you can use it to display a login screen of the value is false
迷鸟归林 2025-02-19 11:00:29

由于您使用的是firebase,因此我建议您添加firebase_auth软件包。然后,您将MyApp用流构建器包裹并提供Firebaseauth.instance.authstatatechanges作为流到firebase_auth随附的流参数,

因此在流构建器的构建器中,返回myApp(),如果snapshot.hasdata,否则返回,否则返回OTP屏幕

Since you are using firebase, i recommed you add the firebase_auth package. And then you wrap the MyApp with a stream builder and supply FirebaseAuth.instance.authStateChanges as stream to the stream parameter which comes with the firebase_auth

So in the builder of the stream builder, return the MyApp() if snapshot.hasData, else return the OTP screen

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文