在闪屏后将已登录的用户重定向到主页,而不是协议页面flutter API

问题描述 投票:0回答:1

我正在使用 API,我希望如果用户之前已经登录,当我在启动屏幕后打开应用程序时,他会直接重定向到主页而不是协议页面(我只希望新登录的用户请参阅协议页)。

这是 main.dart:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:project/firebase_options.dart';
import 'package:project/screens/home_page.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:project/screens/splash_screen.dart';
import 'package:shared_preferences/shared_preferences.dart';

// Import your theme provider class
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);

  await dotenv.load();


}

class MyApp extends StatefulWidget {


  const MyApp({Key? key,}) : super(key: key);

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

class _MyAppState extends State<MyApp> {
  final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;

  @override
  void initState() {
    super.initState();
    _configureFirebaseMessaging();

   
  }

  Future<String?> _loadGlobalId() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    return prefs.getString('globalId');
  }


  @override
  Widget build(BuildContext context) {
    final Brightness brightness = MediaQuery.of(context).platformBrightness;
    final bool isDarkMode = brightness == Brightness.dark;

    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: isDarkMode ? ThemeData.dark() : ThemeData.light(),
      home: SplashScreen()
    );
  }
}

这里是agreement_page.dart:

class AgreementPage extends StatefulWidget {
  @override
  _AgreementPageState createState() => _AgreementPageState();
}

class _AgreementPageState extends State<AgreementPage> {
  bool _accepted = false;
  bool _loggedIn = false;
  String _code = '';
  Color _buttonColor = Colors.grey;
  String _url =
      'https://example.com/auth/example';



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

  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        automaticallyImplyLeading: false,
        backgroundColor: Color(0xff429588),
        title: Text('Terms and Conditions'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Text(
                'End-User License Agreement',
                style: TextStyle(
                  fontSize: 24.0,
                  fontWeight: FontWeight.bold,
                ),
              ),
              SizedBox(height: 16.0),
              Text(
                ),
              SizedBox(height: 16.0),
              Row(
                children: [
                  Checkbox(
                    value: _accepted,
                    onChanged: (value) {
                      setState(() {
                        _accepted = value!;
                        _buttonColor =
                            _accepted ? Color(0xff429588) : Colors.grey;
                      });
                    },
                  ),
                  Text(
                    'I accept the terms and conditions',
                    style: TextStyle(fontSize: 16.0),
                  ),
                ],
              ),
              SizedBox(height: 16.0),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: [
                  ElevatedButton(
                    onPressed: _accepted
                        ? () async {


                            // Show a webview with the url from bottom to top
                            showModalBottomSheet(
                              context: context,
                              isScrollControlled: true,
                              builder: (context) => Container(
                                height:
                                    MediaQuery.of(context).size.height * 0.9,
                                child: WebView(
                                  initialUrl: _url,
                                  javascriptMode: JavascriptMode.unrestricted,
                                  navigationDelegate: (request) {
                                    // Check if the user has logged in successfully
                                    if (request.url.startsWith(
                                        'https://exp.example.com/exp')) {
                                      setState(() {
                                        _loggedIn = true;
                                      });
                                      // Extract the code from the query parameter
                                      final uri = Uri.parse(request.url);
                                      final code = uri.queryParameters['code'];
                                      if (code != null) {
                                        setState(() {
                                          _code = code;
                                        });
                                      }
                                      // Close the webview and navigate to the homepage with the code
                                      Navigator.pop(context);
                                      Navigator.push(
                                        context,
                                        MaterialPageRoute(
                                          builder: (context) => HomePage(
                                            code:
                                                _code, // Pass the code to the homepage
                                          ),
                                        ),
                                      );
                                      return NavigationDecision.prevent;
                                    }
                                    return NavigationDecision.navigate;
                                  },
                                  gestureRecognizers: Set()
                                    ..add(
                                      Factory<VerticalDragGestureRecognizer>(
                                        () => VerticalDragGestureRecognizer(),
                                      ),
                                    ),
                                ),
                              ),
                            );
                          }
                        : null,
                    style: ButtonStyle(
                      backgroundColor:
                          MaterialStateProperty.all<Color>(_buttonColor),
                    ), // Disable the button if not accepted
                    child: Text(
                      'Accept',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                  ElevatedButton(
                    onPressed: () {
                      // Handle the case when the user doesn't accept the agreement.
                      // You can navigate back or perform any other action.

                      // Exit the app
                      exit(0);
                    },
                    style: ButtonStyle(
                      backgroundColor:
                          MaterialStateProperty.all<Color>(Color(0xff429588)),
                    ),
                    child: Text(
                      'Don\'t Accept',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

这是 home_page.dart:

class HomePage extends StatefulWidget {
  const HomePage({Key? key, this.code}) : super(key: key);

  final String? code;

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

class _HomePageState extends State<HomePage> {
  late Future<Map<String, dynamic>> userInfo;

  PersistentTabController _controller =
      PersistentTabController(initialIndex: 0);



  @override
  void initState() {
    super.initState();
    if (widget.code != null && widget.code!.isNotEmpty) {
      userInfo = _authenticate(widget.code!);
    }

  }

  Future<Map<String, dynamic>> _authenticate(String code) async {
    try {
      final tokenData = await AuthService.authenticate(code);
      final accessToken = tokenData['access_token'];
      final refreshToken = tokenData['refresh_token'];
      return await _fetchUserInfo(accessToken);
    } catch (e) {
      // Handle authentication error
      print('Authentication error: $e');
      throw e;
    }
  }

  Future<Map<String, dynamic>> _fetchUserInfo(String accessToken) async {
    try {
      final userInfo = await UserService.fetchUserInfo(accessToken);
      final String userName = userInfo['name'] ?? 'Unknown User';
      final String userEmail = userInfo['email'] ?? 'Unknown Email';
      final String userBirthdate = userInfo['birthdate'] ?? 'Unknown Birthdate';
      final String userGender = userInfo['gender'] ?? 'Unknown Gender';
      final String userRegion =
          userInfo['address']['region'] ?? 'Unknown Region';
      final String userPostalCode =
          userInfo['address']['postal_code'] ?? 'Unknown Postal Code';
      final String userCountry =
          userInfo['address']['country'] ?? 'Unknown Country';
      final String userPreferredUsername =
          userInfo['preferred_username'] ?? 'Unknown Preferred Username';
      final String sub = userInfo['sub'] ?? 'Unknown Global ID';

      return {
        'userName': userName,
        'userEmail': userEmail,
        'userBirthdate': userBirthdate,
        'userGender': userGender,
        'userRegion': userRegion,
        'userPostalCode': userPostalCode,
        'userCountry': userCountry,
        'userPreferredUsername': userPreferredUsername,
        'globalId': sub,
        '_getTabAccessCode': await _getTabAccessCode(sub, accessToken),
      };
    } catch (e) {
      // Handle user info fetch error
      print('Error fetching user information: $e');
      throw e;
    }
  }

  Future<Map<String, dynamic>> _getTabAccessCode(
      String globalId, String accessToken) async {
    try {
      final tabAccessCode =
          await UserService.getTabAccessCode(globalId, accessToken);
      print('Tab Access Code: $tabAccessCode');
      print(
          'Condition result: ${tabAccessCode['pid'] == tabAccessCode['doctorid']}');
      print('PID: ${tabAccessCode['pid']}');
      print('DoctorID: ${tabAccessCode['doctorid']}');

      // Get a reference to the Firestore instance
      FirebaseFirestore firestore = FirebaseFirestore.instance;

      // Determine user type based on pid and doctorid
      String userType = (tabAccessCode['pid'] == tabAccessCode['doctorid'])
          ? 'doctor'
          : 'patient';

      // Store the tab access code and user type in Firestore
      await firestore.collection('users').doc(globalId).set({
        'pid': tabAccessCode['pid'],
        'TabAccCode': tabAccessCode['TabAccCode'],
        'user_type': userType // Add this line
      });

      return {
        'pid': tabAccessCode['pid'],
        'TabAccCode': tabAccessCode['TabAccCode'],
        'user_type': userType // Add this line
      };
    } catch (e) {
      // Handle tab access code fetch error
      print('Error getting Tab Access Code: $e');
      throw e;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: AppDrawer(userInfo: userInfo, controller: _controller),
      body: PersistentTabView(
        context,
        controller: _controller,
        screens: [
          HomeContent(userInfo: userInfo),
          FutureBuilder<Map<String, dynamic>>(
            future: userInfo,
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.waiting) {
                return Center(
                      child: SizedBox(
                        width: 50,
                        height: 50,
                        child: CircularProgressIndicator(),
                      ),
                    );
              } else if (snapshot.hasError) {
                return Text('Error: ${snapshot.error}');
              } else {
                return ConversationPage(
                  TabAccCode: snapshot.data!['_getTabAccessCode']['TabAccCode'],
                  pid: snapshot.data!['_getTabAccessCode']['pid'],
                  user_type: snapshot.data!['_getTabAccessCode']['user_type'],
                  userInfo: userInfo,
                );
              }
            },
          ),
          AppointmentPage(),
          Documents_Page(),
          MyAppsPage()
        ],
        items: [
          PersistentBottomNavBarItem(
            icon: Icon(Icons.home),
            title: ("Home"),
            activeColorPrimary: Color(0xff429588),
            inactiveColorPrimary: Colors.grey,
          ),
          PersistentBottomNavBarItem(
            icon: Icon(Icons.message),
            title: ("Messages"),
            activeColorPrimary: Color(0xff429588),
            inactiveColorPrimary: Colors.grey,
          ),
          PersistentBottomNavBarItem(
            icon: Icon(Icons.calendar_month),
            title: ("Appointments"),
            activeColorPrimary: Color(0xff429588),
            inactiveColorPrimary: Colors.grey,
          ),
          PersistentBottomNavBarItem(
            icon: Icon(Icons.edit_document),
            title: ("Documents"),
            activeColorPrimary: Color(0xff429588),
            inactiveColorPrimary: Colors.grey,
          ),
          PersistentBottomNavBarItem(
            icon: Icon(Icons.apps),
            title: ("My Apps"),
            activeColorPrimary: Color(0xff429588),
            inactiveColorPrimary: Colors.grey,
          ),
        ],
      ),
    );
  }
}

我尝试像这样共享首选项:

splash_screen.dart

void initState() {
    super.initState();
    SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);

    // Introduce a 2-second delay before navigating to the agreement page
    Future.delayed(Duration(seconds: 2), () async {
      // Get the instance of SharedPreferences
      SharedPreferences prefs = await SharedPreferences.getInstance();
      // Check if the user is already logged in
      bool isLoggedIn = prefs.getBool('isLoggedIn') ?? false;
      // Use Navigator to navigate based on the login state
      Navigator.of(context).pushReplacement(
        MaterialPageRoute(
            builder: (context) => isLoggedIn ? HomePage() : AgreementPage()),
      );
    });
  }

在agreement_page.dart中,用户接受:

 ElevatedButton(
                    onPressed: _accepted
                        ? () async {
                            SharedPreferences prefs =
                                await SharedPreferences.getInstance();
                            prefs.setBool('isLoggedIn',
                                true); // Set to true when logging in
                        
                            // Show a webview with the url from bottom to top
                            showModalBottomSheet(
                              context: context,
                              isScrollControlled: true,
                              builder: (context) => Container(
                                height:
                                    MediaQuery.of(context).size.height * 0.9,
                                child: WebView(
                                  initialUrl: _url,
                                  javascriptMode: JavascriptMode.unrestricted,
                                  navigationDelegate: (request) {
                                    // Check if the user has logged in successfully
                                    if (request.url.startsWith(
                                        'https://example.com')) {
                                      setState(() {
                                        _loggedIn = true;
                                      });
                                      // Extract the code from the query parameter
                                      final uri = Uri.parse(request.url);
                                      final code = uri.queryParameters['code'];
                                      if (code != null) {
                                        setState(() {
                                          _code = code;
                                        });
                                      }
                                      // Close the webview and navigate to the homepage with the code
                                      Navigator.pop(context);
                                      Navigator.push(
                                        context,
                                        MaterialPageRoute(
                                          builder: (context) => HomePage(
                                            code:
                                                _code, // Pass the code to the homepage
                                          ),
                                        ),
                                      );
                                      return NavigationDecision.prevent;
                                    }
                                    return NavigationDecision.navigate;
                                  },
                                  gestureRecognizers: Set()
                                    ..add(
                                      Factory<VerticalDragGestureRecognizer>(
                                        () => VerticalDragGestureRecognizer(),
                                      ),
                                    ),
                                ),
                              ),
                            );
                          }
                        : null,
                    style: ButtonStyle(
                      backgroundColor:
                          MaterialStateProperty.all<Color>(_buttonColor),
                    ), // Disable the button if not accepted
                    child: Text(
                      'Accept',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),

但我从 home_page.dart 收到错误:

“LateError(LateInitializationError:字段'userInfo'尚未初始化。)”

如果有人可以帮忙的话。

flutter dart authentication logic
1个回答
0
投票

您在 home_page.dart 中遇到 LateInitializationError ,因为当您从AgreementPage导航到HomePage时,您正在传递代码,但是当您从Splash导航到HomePage时,您没有传递任何代码,因此您的userInfo不会被初始化,因为条件失败。

if (widget.code != null && widget.code!.isNotEmpty) {
  userInfo = _authenticate(widget.code!);
}

从 Splash 导航时,不要在主页中遇到任何 LateInitializationError 密码。

希望您遇到问题并且此解决方案适合您。

© www.soinside.com 2019 - 2024. All rights reserved.