You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter角色权限应用如何实现关闭重启后保持登录状态?

解决Flutter Firebase应用重启后丢失登录状态的问题

当前代码仅在用户主动点击登录按钮时处理路由跳转,未在应用启动时检测Firebase Auth中已持久化的用户会话,也没有监听用户状态变化。Firebase Auth默认会自动持久化用户会话,只需通过状态监听即可实现重启后自动登录。

步骤1:在应用入口监听用户登录状态

修改应用入口(如main.dart),通过StreamBuilder监听Firebase Auth的用户状态变化,根据登录状态自动跳转对应页面:

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:telenursingapp/sign_in.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';
import 'package:cloud_firestore/cloud_firestore.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // 若未初始化Firebase,取消注释以下代码
  // await Firebase.initializeApp();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // 根据用户角色返回对应首页
  Widget getHomePage(User user) {
    return FutureBuilder<DocumentSnapshot>(
      future: FirebaseFirestore.instance.collection('users').doc(user.uid).get(),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Scaffold(body: Center(child: CircularProgressIndicator()));
        }
        if (!snapshot.hasData || !snapshot.data!.exists) {
          return const SignIn();
        }
        String role = snapshot.data!.get('role');
        switch (role) {
          case "Patient":
            return const PatientsPortal();
          case "Consultant":
            return const ConsultantPortal();
          case "New Admin":
            return const AdminPortal();
          case "Telenurse":
            return const TelenursePortal();
          default:
            return const SignIn();
        }
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'YourDoc',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: StreamBuilder<User?>(
        stream: FirebaseAuth.instance.authStateChanges(),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Scaffold(body: Center(child: CircularProgressIndicator()));
          }
          if (snapshot.hasData && snapshot.data != null) {
            // 用户已登录,跳转对应角色页面
            return getHomePage(snapshot.data!);
          } else {
            // 用户未登录,显示登录页
            return const SignIn();
          }
        },
      ),
    );
  }
}

步骤2:优化SignIn页面的登录逻辑

保留原有登录验证逻辑,移除冗余的路由跳转(由入口的StreamBuilder自动处理状态变化),并添加错误提示:

void signIn(String email, String password) async {
  if (_formkey.currentState!.validate()) {
    try {
      await FirebaseAuth.instance.signInWithEmailAndPassword(
        email: email,
        password: password,
      );
      // 登录成功后清空输入框并隐藏加载动画
      emailController.clear();
      passwordController.clear();
      setState(() {
        visible = false;
      });
    } on FirebaseAuthException catch (e) {
      setState(() {
        visible = false;
      });
      // 给用户显示登录错误提示
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text(e.message ?? '登录失败,请重试')),
      );
    }
  }
}

关键说明

  • authStateChanges()会在用户登录、登出、会话过期或应用重启时触发,自动检测已持久化的用户会话
  • 通过FutureBuilder从Firestore获取用户角色,确保角色数据加载完成后再跳转对应页面
  • Firebase Auth默认开启会话持久化,无需额外使用本地存储(如SharedPreferences)保存用户信息

内容的提问来源于stack exchange,提问作者Jay Faculty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 13:25:26