我有一个关于 flutter 中的 Firestore 的问题

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

我对 Flutter 中的 Firestore 有疑问,因为我的应用程序陷入僵局,因为我有一个登录页面,其中包含用于登录的国家/地区、电子邮件和密码字段,我希望能够使用这 3 个字段对用户进行身份验证但是当我需要通过 Firestore 使用该国家/地区时,我无法检索它并且该字段用于验证,在我看来,要从 Firestore 检索字段,您无法通过 Firebase Auth 退出,因为您需要 currentUser 来访问该字段,我发现这很奇怪,我无法执行此逻辑,它首先检查用户是否经过身份验证,然后访问 Firebase 中的国家/地区字段并验证登录。有没有人做过类似的事情?

这是我的登录页面

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:whatsapp/Pages/reset_page.dart';
import 'package:whatsapp/Pages/sign_up.dart';
import 'package:whatsapp/auth/auth_page.dart';
import 'package:whatsapp/components/dropdown_button.dart';
import 'package:whatsapp/components/text_field.dart';

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

  @override
  State<LoginPage> createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  final formKey = GlobalKey<FormState>();
  String? name;
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();
  bool obscureText = true;
  String? _selectedCountry;  
  String? countryValue;
  String? errorMessage;
  String? errorMessageEmail;
  String? errorMessagePassword;
  String? errorMessageCountry;
  final AuthPage _authPage = AuthPage();  
  

  _validateFields() async {
    String email = _emailController.text;
    String password = _passwordController.text;     

    if (_selectedCountry == 'United Kingdom') {
      if (email.isNotEmpty && email.contains("@")) {
        if (password.isNotEmpty) {
          errorMessage = null;
          errorMessageEmail = null;
          errorMessagePassword = null;
          signUserIn();
        } else {
          setState(() {
            errorMessagePassword = 'Please enter your password';
          });
        }
      } else {
        setState(() {
          errorMessageEmail = 'Please enter your E-mail ';
        });
      }
    } else {
      setState(() {
        errorMessage = 'Please enter your country';
      });
    }
  }

  signUserIn() async {
    String email = _emailController.text;
    String password = _passwordController.text;         
   
    String? authResult = await _authPage.loginUser(
        context, mounted, email, password);   
            
    setState(() {
      errorMessage = authResult;
    });
  }

  @override
  Widget build(BuildContext context) {
    final deviceWidth = MediaQuery.of(context).size.width;
    final deviceHeight = MediaQuery.of(context).size.height;

    return PopScope(
      canPop: false,
      child: SafeArea(
        child: Scaffold(
            backgroundColor: const Color(0xFF101d25),
            appBar: AppBar(
                automaticallyImplyLeading: false,
                toolbarHeight: deviceHeight < 500
                    ? deviceHeight * 0.15
                    : deviceHeight * 0.09,
                centerTitle: true,
                backgroundColor: const Color(0xFF101d25),
                title: const Padding(
                  padding: EdgeInsets.only(top: 10),
                  child: Text('Verify your E-mail',
                      style: TextStyle(
                          color: Color(0xFF0ca886),
                          fontWeight: FontWeight.bold)),
                ),
                actions: [
                  IconButton(
                    icon: const Icon(Icons.more_vert, color: Color(0xFF0ca886)),
                    onPressed: () {},
                  ),
                ]),
            body: SingleChildScrollView(
              child: Center(
                child: SizedBox(
                  height: deviceHeight < 500
                      ? deviceHeight * 1.30
                      : deviceHeight * 0.80,
                  width: deviceWidth < 500
                      ? deviceWidth * 0.80
                      : deviceWidth * 0.60,
                  child: Column(
                    //mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      const Padding(
                        padding: EdgeInsets.only(top: 10),
                        child: Text(
                          'WhatsApp will verify your registred\n e-mail. Enter your country, e-mail and password:',
                          textAlign: TextAlign.center,
                          style: TextStyle(fontSize: 18, color: Colors.white),
                        ),
                      ),
                      SizedBox(height: deviceHeight * 0.05),
                      Form(
                        key: formKey,
                        child: Column(
                          children: [
                            CustomDropDownButton(
                              value: _selectedCountry,
                              onChanged: (newValue) {
                                _selectedCountry = newValue;
                              },
                            ),
                            SizedBox(height: deviceHeight * 0.03),
                            CustomTextField(
                              labelText: 'E-mail',
                              keyboardType: TextInputType.emailAddress,
                              controller: _emailController,
                              onChanged: (value) {
                                if (value.isNotEmpty && value.contains("@")) {
                                  errorMessageEmail = null;
                                }
                              },
                              errorText: errorMessageEmail,
                            ),
                            SizedBox(height: deviceHeight * 0.02),
                            CustomTextField(
                              labelText: 'Password',
                              suffixIcon: GestureDetector(
                                onTap: () {
                                  setState(() {
                                    obscureText = !obscureText;
                                  });
                                },
                                child: Padding(
                                  padding: EdgeInsets.only(
                                      top: deviceHeight < 500
                                          ? deviceHeight * 0.055
                                          : deviceHeight * 0.025),
                                  child: FaIcon(
                                      obscureText
                                          ? FontAwesomeIcons.solidEye
                                          : FontAwesomeIcons.solidEyeSlash,
                                      color: const Color(0xFF0ca886),
                                      size: 22),
                                ),
                              ),
                              keyboardType: TextInputType.visiblePassword,
                              obscureText: obscureText,
                              onChanged: (value) {
                                if (value.isNotEmpty) {
                                  errorMessagePassword = null;
                                }
                              },
                              controller: _passwordController,
                              errorText: errorMessagePassword,
                            ),
                          ],
                        ),
                      ),
                      SizedBox(height: deviceHeight * 0.02),
                      RichText(
                        text: TextSpan(children: [
                          TextSpan(
                              text: 'Forgot your password?',
                              style: const TextStyle(
                                  color: Colors.blue, fontSize: 15),
                              recognizer: TapGestureRecognizer()
                                ..onTap = () {
                                  //print('reset password');
                                  Navigator.push(
                                      context,
                                      MaterialPageRoute(
                                          builder: (context) =>
                                              const ResetPasswordPage()));
                                }),
                        ]),
                      ),
                      SizedBox(height: deviceHeight * 0.01),
                      Text(
                        errorMessage ??
                            '', // Exibe a mensagem de erro ou uma string vazia
                        style: const TextStyle(
                          color:
                              Colors.red, // Cor vermelha para indicar um erro
                          fontSize: 16,
                        ),
                      ),
                      SizedBox(height: deviceHeight * 0.01),
                      SizedBox(
                        height: deviceHeight < 500
                            ? deviceHeight * 0.15
                            : deviceHeight * 0.06,
                        width: deviceWidth < 500
                            ? deviceWidth * 0.68
                            : deviceWidth * 0.38,
                        child: ElevatedButton(
                          style: ElevatedButton.styleFrom(
                              shape: BeveledRectangleBorder(
                                borderRadius: BorderRadius.circular(2),
                              ),
                              backgroundColor: const Color(0xFF0ca886)),
                          onPressed: () {
                            _validateFields();
                          },
                          child: Padding(
                            padding: EdgeInsets.symmetric(
                                vertical: deviceWidth * 0.012),
                            child: const Text(
                              'Enter',
                              style: TextStyle(
                                  color: Color(0xFF121a21), fontSize: 18),
                            ),
                          ),
                        ),
                      ),
                      Padding(
                        padding: EdgeInsets.only(top: deviceHeight * 0.02),
                        child: RichText(
                            text: TextSpan(children: [
                          const TextSpan(
                              text: "Don't have a account yet?  ",
                              style:
                                  TextStyle(color: Colors.white, fontSize: 14)),
                          TextSpan(
                              text: 'SignUp.',
                              style: const TextStyle(
                                  color: Colors.blue,
                                  fontSize: 14,
                                  fontWeight: FontWeight.bold),
                              recognizer: TapGestureRecognizer()
                                ..onTap = () {
                                  Navigator.push(
                                      context,
                                      MaterialPageRoute(
                                          builder: (context) =>
                                              const SignupPage()));
                                }),
                        ])),
                      )
                    ],
                  ),
                ),
              ),
            )),
      ),
    );
  }
}

这是我的 AuthPage

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:whatsapp/Pages/home.dart';

class AuthPage {
  final _auth = FirebaseAuth.instance;   

  Future loginUser(
      BuildContext context, bool mounted, String email, String password) async {
    try {
      // Exibe um CircularProgress antes de Autenticar
      showCircularIndicator(context);

      // await Future.delayed(const Duration(milliseconds: 5000));
      await _auth.signInWithEmailAndPassword(email: email, password: password);
      if (!mounted) return;
          Navigator.pop(context);
          _navigateToNextScreen(context);
      
      // Pegar o usuario atual caso autenticado
      /*
      User? user = FirebaseAuth.instance.currentUser;
      if (user != null) {
        // Usuário está autenticado, agora você pode acessar o campo país
        String? country = await getCountryForUser(user);        
        if (country != null) {         
          if (!mounted) return;
          Navigator.pop(context);
          _navigateToNextScreen(context);
          
        } else{
          return null;
        }
        // Faça o que precisa ser feito com o campo país
      } else {
        // Usuário não autenticado
        print('Usuário não autenticado');
      }
      */

      // Se a autenticação for bem-sucedida, navegue para a próxima tela
    } on FirebaseAuthException catch (e) {
      // Esconde o circularIndicator
      if (!mounted) return;
      Navigator.pop(context);
      // Se houver um erro, chame a função de retorno de erro
      if (e.code == 'invalid-credential') {
        return 'E-mail or Password invalid.';
      } else if (e.code == 'too-many-requests') {
        return 'Login failed, exceed requests try again soon.';
      }
    }
  }

  void _navigateToNextScreen(BuildContext context) {
    Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => const HomePage()),
    );
  }

  void showCircularIndicator(BuildContext context) {
    showDialog(
        context: context,
        builder: (BuildContext context) {
          return const Center(
            child: CircularProgressIndicator(color: Color(0xFF0ca886)),
          );
        });
  }

  Future<String?> getCountryForUser(User? user) async {
    DocumentSnapshot<Map<String, dynamic>> snapshot = await FirebaseFirestore
        .instance
        .collection("users")
        .doc(user?.uid)
        .get();
    if (snapshot.exists) {
      return snapshot.data()?['country'];
    } else {
      return null;
    }
  }
}

我尝试检索 AuthPage 中的 Firestore 字段,但无法使用它在登录页面上进行验证,所以我陷入了困境,想了解是否有人可以帮助我。谢谢...

flutter google-cloud-firestore firebase-authentication
1个回答
0
投票

我正在尝试。

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:whatsapp/Pages/reset_page.dart';
import 'package:whatsapp/Pages/sign_up.dart';
import 'package:whatsapp/auth/auth_page.dart';
import 'package:whatsapp/components/dropdown_button.dart';
import 'package:whatsapp/components/text_field.dart';

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

  @override
  State<LoginPage> createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  final formKey = GlobalKey<FormState>();
  String? name;
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();
  bool obscureText = true;
  String? _selectedCountry;
  String? countryValue;
  String? errorMessage;
  String? errorMessageEmail;
  String? errorMessagePassword;
  String? errorMessageCountry;
  final AuthPage _authPage = AuthPage();

  _validateFields() async {
    String email = _emailController.text;
    String password = _passwordController.text;
    String? autResult =
        await _authPage.loginUser(context, mounted, email, password);
    User? user = FirebaseAuth.instance.currentUser;
    countryValue = await _authPage.getCountryForUser(user);

    if (_selectedCountry == countryValue) {
      if (email.isNotEmpty && email.contains("@")) {
        if (password.isNotEmpty) {
          setState(() {
            errorMessage = null;
          });
        } else {
          setState(() {
            errorMessagePassword = 'Please enter your password';
          });
        }
      } else {
        setState(() {
          errorMessageEmail = 'Please enter your email';
        });
      }
    } else {
      setState(() {
        errorMessage = 'Please enter your country';
      });
    }
    setState(() {
      errorMessage = autResult;
    });
  }

  @override
  Widget build(BuildContext context) {
    final deviceWidth = MediaQuery.of(context).size.width;
    final deviceHeight = MediaQuery.of(context).size.height;

    return PopScope(
      canPop: false,
      child: SafeArea(
        child: Scaffold(
            backgroundColor: const Color(0xFF101d25),
            appBar: AppBar(
                automaticallyImplyLeading: false,
                toolbarHeight: deviceHeight < 500
                    ? deviceHeight * 0.15
                    : deviceHeight * 0.09,
                centerTitle: true,
                backgroundColor: const Color(0xFF101d25),
                title: const Padding(
                  padding: EdgeInsets.only(top: 10),
                  child: Text('Verify your E-mail',
                      style: TextStyle(
                          color: Color(0xFF0ca886),
                          fontWeight: FontWeight.bold)),
                ),
                actions: [
                  IconButton(
                    icon: const Icon(Icons.more_vert, color: Color(0xFF0ca886)),
                    onPressed: () {},
                  ),
                ]),
            body: SingleChildScrollView(
              child: Center(
                child: SizedBox(
                  height: deviceHeight < 500
                      ? deviceHeight * 1.30
                      : deviceHeight * 0.80,
                  width: deviceWidth < 500
                      ? deviceWidth * 0.80
                      : deviceWidth * 0.60,
                  child: Column(
                    //mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      const Padding(
                        padding: EdgeInsets.only(top: 10),
                        child: Text(
                          'WhatsApp will verify your registred\n e-mail. Enter your country, e-mail and password:',
                          textAlign: TextAlign.center,
                          style: TextStyle(fontSize: 18, color: Colors.white),
                        ),
                      ),
                      SizedBox(height: deviceHeight * 0.05),
                      Form(
                        key: formKey,
                        child: Column(
                          children: [
                            CustomDropDownButton(
                              value: _selectedCountry,
                              onChanged: (newValue) {
                                setState(() {
                                  _selectedCountry = newValue;
                                  errorMessage = null;
                                });
                              },
                              validator: (newValue) {
                                if (newValue == null) {
                                  errorMessage = 'Please enter your country';
                                }
                                return errorMessage;
                              },
                            ),
                            SizedBox(height: deviceHeight * 0.03),
                            CustomTextField(
                              labelText: 'E-mail',
                              keyboardType: TextInputType.emailAddress,
                              controller: _emailController,
                              onChanged: (value) {
                                if (value.isNotEmpty && value.contains("@")) {
                                  errorMessageEmail = null;
                                }
                              },
                              errorText: errorMessageEmail,
                            ),
                            SizedBox(height: deviceHeight * 0.02),
                            CustomTextField(
                              labelText: 'Password',
                              suffixIcon: GestureDetector(
                                onTap: () {
                                  setState(() {
                                    obscureText = !obscureText;
                                  });
                                },
                                child: Padding(
                                  padding: EdgeInsets.only(
                                      top: deviceHeight < 500
                                          ? deviceHeight * 0.055
                                          : deviceHeight * 0.025),
                                  child: FaIcon(
                                      obscureText
                                          ? FontAwesomeIcons.solidEye
                                          : FontAwesomeIcons.solidEyeSlash,
                                      color: const Color(0xFF0ca886),
                                      size: 22),
                                ),
                              ),
                              keyboardType: TextInputType.visiblePassword,
                              obscureText: obscureText,
                              onChanged: (value) {
                                if (value.isNotEmpty) {
                                  errorMessagePassword = null;
                                }
                              },
                              controller: _passwordController,
                              errorText: errorMessagePassword,
                            ),
                          ],
                        ),
                      ),
                      SizedBox(height: deviceHeight * 0.02),
                      RichText(
                        text: TextSpan(children: [
                          TextSpan(
                              text: 'Forgot your password?',
                              style: const TextStyle(
                                  color: Colors.blue, fontSize: 15),
                              recognizer: TapGestureRecognizer()
                                ..onTap = () {
                                  //print('reset password');
                                  Navigator.push(
                                      context,
                                      MaterialPageRoute(
                                          builder: (context) =>
                                              const ResetPasswordPage()));
                                }),
                        ]),
                      ),
                      SizedBox(height: deviceHeight * 0.01),
                      Text(
                        errorMessage ??
                            '', // Exibe a mensagem de erro ou uma string vazia
                        style: const TextStyle(
                          color:
                              Colors.red, // Cor vermelha para indicar um erro
                          fontSize: 16,
                        ),
                      ),
                      SizedBox(height: deviceHeight * 0.01),
                      SizedBox(
                        height: deviceHeight < 500
                            ? deviceHeight * 0.15
                            : deviceHeight * 0.06,
                        width: deviceWidth < 500
                            ? deviceWidth * 0.68
                            : deviceWidth * 0.38,
                        child: ElevatedButton(
                          style: ElevatedButton.styleFrom(
                              shape: BeveledRectangleBorder(
                                borderRadius: BorderRadius.circular(2),
                              ),
                              backgroundColor: const Color(0xFF0ca886)),
                          onPressed: () {
                            _validateFields();
                          },
                          child: Padding(
                            padding: EdgeInsets.symmetric(
                                vertical: deviceWidth * 0.012),
                            child: const Text(
                              'Enter',
                              style: TextStyle(
                                  color: Color(0xFF121a21), fontSize: 18),
                            ),
                          ),
                        ),
                      ),
                      Padding(
                        padding: EdgeInsets.only(top: deviceHeight * 0.02),
                        child: RichText(
                            text: TextSpan(children: [
                          const TextSpan(
                              text: "Don't have a account yet?  ",
                              style:
                                  TextStyle(color: Colors.white, fontSize: 14)),
                          TextSpan(
                              text: 'SignUp.',
                              style: const TextStyle(
                                  color: Colors.blue,
                                  fontSize: 14,
                                  fontWeight: FontWeight.bold),
                              recognizer: TapGestureRecognizer()
                                ..onTap = () {
                                  Navigator.push(
                                      context,
                                      MaterialPageRoute(
                                          builder: (context) =>
                                              const SignupPage()));
                                }),
                             ])),
                            )
                           ],
                          ),
                      ),
              ),
            )),
      ),
    );
  }
}
    
© www.soinside.com 2019 - 2024. All rights reserved.