Firebase 身份验证:电子邮件验证在 Flutter 中始终返回“电子邮件未注册”

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

我正在开发一个 Flutter 应用程序,其中使用 Firebase 身份验证进行电子邮件和密码登录。该应用程序的流程是,用户首先在登录屏幕上输入电子邮件。单击“继续”后,应用程序会检查电子邮件是否已在 Firebase 中注册。如果未注册,他们会收到一条消息,要求他们创建一个帐户。如果电子邮件已注册,他们将进入第二个屏幕,可以在其中输入密码。

我面临的问题是,即使我输入在 Firebase 中注册的电子邮件(我可以在 Firebase 控制台中看到它),它仍然返回消息“电子邮件未注册。”

这是电子邮件屏幕的相关代码,第一个是我创建的用于检查电子邮件是否已验证的函数:

Future<void> checkEmail() async {
  String email = emailController.text.trim();

  setState(() {
    isLoading = true;
  });

  try {
    // Attempt to fetch sign-in methods for the email
    List<String> signInMethods =
        await FirebaseAuth.instance.fetchSignInMethodsForEmail(email);

    if (signInMethods.isEmpty) {
      // Email is not registered
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('Email is not registered. Please create an account.'),
        ),
      );
    } else {
      // Email is registered, proceed to password screen
      Navigator.of(context).push(
        MaterialPageRoute(
          builder: (context) => SigninScreenPassword(
            email: email,
          ),
        ),
      );
    }
  } catch (e) {
    // Handle errors
    print('Error fetching sign-in methods: $e');
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text('An error occurred: $e'),
      ),
    );
  } finally {
    setState(() {
      isLoading = false;
    });
  }
}

您可以在下面看到上下文屏幕的完整代码,包括我调用该函数的位置:

// ignore_for_file: deprecated_member_use

import 'package:cloture/screens/authentication/create_account_screen.dart';
import 'package:cloture/screens/authentication/sign_in_screen_password.dart';
import 'package:cloture/utilities/buttons.dart';
import 'package:cloture/utilities/colors.dart';
import 'package:cloture/utilities/text.dart';
import 'package:cloture/utilities/textfield.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:cloture/gen/assets.gen.dart';

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

  @override
  State<SigninScreenEmail> createState() => _SigninScreenEmailState();
}

class _SigninScreenEmailState extends State<SigninScreenEmail> {
  TextEditingController emailController = TextEditingController();
  final _formKey = GlobalKey<FormState>();
  bool isLoading = false;

  Future<void> checkEmail() async {
    String email = emailController.text.trim();

    setState(() {
      isLoading = true;
    });

    try {
      // Fetch sign-in methods for the email
      List<String> signInMethods =
          await FirebaseAuth.instance.fetchSignInMethodsForEmail(email);

      if (signInMethods.isEmpty) {
        // Email is not registered
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text('Email is not registered. Please create an account.'),
          ),
        );
      } else {
        // Debugging: Print the sign-in methods
        print("Sign-in methods for email: $signInMethods");

        // Email is registered, proceed to password screen
        Navigator.of(context).push(
          MaterialPageRoute(
            builder: (context) => SigninScreenPassword(
              email: email,
            ),
          ),
        );
      }
    } catch (e) {
      // Check for Firebase-specific errors
      print('Error fetching sign-in methods: $e');
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text('An error occurred: $e'),
        ),
      );
    } finally {
      setState(() {
        isLoading = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: white100,
      body: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 27, vertical: 123),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              reusableText(
                'Sign in',
                32.sp,
                FontWeight.bold,
                black100,
                -0.41,
                TextAlign.left,
              ),
              SizedBox(height: 32.h),
              Form(
                key: _formKey,
                child: authTextField(
                    hintText: 'Email Address',
                    controller: emailController,
                    keyboardType: TextInputType.emailAddress,
                    textInputAction: TextInputAction.done,
                    validator: (value) {
                      if (value == null || value.isEmpty) {
                        return 'Please enter your email';
                      } else if (!RegExp(r'^[^@]+@[^@]+\.[^@]+')
                          .hasMatch(value)) {
                        return 'Please enter a valid email address';
                      }
                      return null;
                    }),
              ),
              SizedBox(
                height: 16.h,
              ),
              appButton(
                'Continue',
                primary200,
                white100,
                47.h,
                344.w,
                100.r,
                16.sp,
                FontWeight.w500,
                Colors.transparent,
                -0.5,
                () {
                  if (_formKey.currentState!.validate()) {
                    checkEmail();
                  }
                },
              ),
              SizedBox(
                height: 16.h,
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.start,
                children: [
                  reusableText(
                    'Don\'t have an account?',
                    12.sp,
                    FontWeight.w500,
                    black100,
                    -0.5,
                    TextAlign.left,
                  ),
                  SizedBox(
                    width: 8.w,
                  ),
                  GestureDetector(
                    onTap: () {
                      Navigator.of(context).push(
                        MaterialPageRoute(
                          builder: (context) => const CreateAccountScreen(),
                        ),
                      );
                    },
                    child: reusableText(
                      'Create One',
                      12.sp,
                      FontWeight.bold,
                      primary200,
                      -0.5,
                      TextAlign.left,
                    ),
                  ),
                ],
              ),
              SizedBox(
                height: 71.h,
              ),
              authButton(
                'Continue with Apple',
                Assets.images.appleSvg.image(height: 24.h),
                () {},
              ),
              SizedBox(
                height: 12.h,
              ),
              authButton(
                'Continue with Google',
                Assets.images.googlePng0.image(height: 24.h),
                () {},
              ),
              SizedBox(
                height: 12.h,
              ),
              authButton(
                'Continue with Facebook',
                Assets.images.facebookPng0.image(height: 24.h),
                () {},
              ),
              SizedBox(
                height: 71.h,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

我尝试过的: 已验证 Firebase 项目设置是否正确,因为我可以在 Firebase 控制台中看到注册的电子邮件。 检查输入的电子邮件是否有效并且与 Firebase 中的电子邮件匹配。 在将电子邮件发送到

fetchSignInMethodsForEmail()
之前尝试修剪电子邮件以删除任何前导或尾随空格。

预期行为: 如果 Firebase 中存在电子邮件,应用程序应导航至密码屏幕。 如果电子邮件不存在,它应该显示一条消息,要求用户创建帐户。 实际行为: 即使我输入 Firebase 中存在的电子邮件,我也会收到消息“电子邮件未注册。”

问题: 即使 Firebase 中存在电子邮件,但电子邮件未被识别为已注册的问题,可能是什么原因导致的?我该如何解决这个问题,以便应用程序正确识别注册的电子邮件?

flutter firebase dart firebase-realtime-database firebase-authentication
1个回答
0
投票

在假设电子邮件未注册之前,请确保您正在检查所有可能的登录方法(Google、Facebook、密码等)。

if (signInMethods.contains('password')) {
  // Proceed to password screen
} else if (signInMethods.isNotEmpty) {
  // Email registered with another provider (Google, Facebook, etc.)
  // Prompt the user to use their associated sign-in method
} else {
  // Email is not registered
}

在使用 Firebase 检查之前将电子邮件转换为小写。 进行适当的错误处理。

} catch (e) {
  if (e is FirebaseAuthException) {
    print('FirebaseAuthException: ${e.message}');
  } else {
    print('Error: $e');
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.