为啥我无法将电子邮件/密码链接到 Firebase Flutter 中 Google 登录提供商中存在的同一电子邮件?

Posted

技术标签:

【中文标题】为啥我无法将电子邮件/密码链接到 Firebase Flutter 中 Google 登录提供商中存在的同一电子邮件?【英文标题】:why i can't link email/password to the same email exist in google sign in provider in firebase flutter?为什么我无法将电子邮件/密码链接到 Firebase Flutter 中 Google 登录提供商中存在的同一电子邮件? 【发布时间】:2021-01-30 14:44:11 【问题描述】:

我曾与 google 登录和 firebase auth 的电子邮件/密码提供商合作,我注意到在我与电子邮件/密码提供商注册后,我在 google_sign_in 提供商使用相同的电子邮件 使用登录并在注册电子邮件后注销,这样我就可以以我的身份进入 authscreen,但是当我在使用 google_sign_in 并从谷歌注销并尝试注册后尝试使用另一个帐户进行反向操作时,它给了我错误 电子邮件已经存在,当我尝试登录时,它给我错误密码错误,即使我认为我写谷歌电子邮件的密码 100% 正确,所以有没有办法启用签名 here is photo the error shown in snackbar of login and here is sign up error and this is the two emails in firebase auth

choice_provier_screen 代码

  import 'package:firebase_auth/firebase_auth.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter_app/tabs.dart';
    import './signInOrLogIn_Screen.dart';
    import 'package:google_sign_in/google_sign_in.dart';

    Future<UserCredential> signinWithGoogle() async 
        final GoogleSignInAccount googleuser = await GoogleSignIn().signIn();
        final GoogleSignInAuthentication googleauth = await googleuser.authentication;
        final GoogleAuthCredential credential = GoogleAuthProvider.credential(
        accessToken: googleauth.accessToken,
    idToken: googleauth.idToken,
  );
  return await FirebaseAuth.instance.signInWithCredential(credential);


Widget createRaised(
    Color backgroundcolor,
    String image,
    String name,
    Color textcolor,
    Function f) 
  return SizedBox(
    width: 290,
    child: RaisedButton.icon(
      onPressed: f,
      label: Text(
        name,
        style: TextStyle(fontSize: 18, color: textcolor),
      ),
      icon: Padding(
        padding: const EdgeInsets.only(right: 10),
        child: Image.asset(
          image,
          height: 20,
          fit: BoxFit.fill,
        ),
      ),
      padding: EdgeInsets.all(10),
      shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(30),
          side: BorderSide(color: Colors.black)),
      color: backgroundcolor,
      splashColor: Colors.transparent,
      highlightColor: Colors.transparent,
    ),
  );


    class ChoiceAuthMehod extends StatelessWidget 
      @override
      Widget build(BuildContext context) 
        return Scaffold(
          appBar: AppBar(),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                SizedBox(
                  width: 290,
                  child: RaisedButton(
                    color: Colors.black,
                    child: Text(
                      'Sign up / log in',
                      style: TextStyle(color: Colors.red, fontSize: 18),
                    ),
                    onPressed: () 
                      Navigator.of(context)
                          .pushReplacementNamed(AuthScreen.routeName);
                    ,
                    padding: EdgeInsets.all(10),
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(30),
                        side: BorderSide(color: Colors.black)),
                  ),
                ),
                SizedBox(
                  height: 10,
                ),
                createRaised(
                    backgroundcolor: Colors.white,
                    image: 'lib/google_transperant.png',
                    name: 'sign up with google',
                    f: () => signinWithGoogle().then((value) 
                          print('email google : $value.user.displayName');
                          Navigator.of(context)
                              .pushReplacementNamed(Tabs.routeName);
                        ),
                    textcolor: Colors.black),
              ],
            ),
          ),
        );
      
    
登录/登录代码
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_app/checkuserstate.dart';
import './textfiledform.dart';

class AuthScreen extends StatefulWidget 
  static const routeName ='/Auth-screen';
  @override
  _AuthScreenState createState() => _AuthScreenState();


class _AuthScreenState extends State<AuthScreen> 
  final _formKey = GlobalKey<FormState>();
  final _scaffoldKey = GlobalKey<ScaffoldState>();

  // if false login else will change to sign in when user hit the signUp button
  bool changeAuthMode = false;

  bool autoError = false;
  String email ;
  FocusNode emailNode = FocusNode(), pNode = FocusNode(), cpNode = FocusNode();
  bool _loading = false;
  final _passwordController = TextEditingController();

  void changeInputState() 
    setState(() 
      changeAuthMode = !changeAuthMode;
    );
  

  void createSnackBar(String e) 
    _scaffoldKey.currentState.removeCurrentSnackBar();
    _scaffoldKey.currentState.showSnackBar(SnackBar(
      content: Text(e),
      backgroundColor: Colors.red,
      action: SnackBarAction(
        label: 'ok',
        onPressed: () ,
      ),
    ),
    );
  

  Future<String> signUp(String er) async 
    try 
      var result = await FirebaseAuth.instance.createUserWithEmailAndPassword(
          email: email, password: _passwordController.text);
      await result.user.sendEmailVerification().then((_)  
         result.user.reload().then((value) => Navigator.pushReplacementNamed(
          context,
          CheckUserState.routeName,
        ));
      );
     on FirebaseAuthException catch (e) 
      if (e.code == 'weak-password') 
        er = 'The password provided is too weak.';
       else if (e.code == 'email-already-in-use') 
        er = 'The account already exists for that email.';
      
     catch (e) 
      er = e.toString();
    
    return er;
  

  Future<String> login(String er) async 
    try 
      await FirebaseAuth.instance
          .signInWithEmailAndPassword(
          email: email, password: _passwordController.text)
          .then((value) 

        print('login page = $FirebaseAuth.instance.currentUser.emailVerified');

          Navigator.of(context).pushReplacementNamed(CheckUserState.routeName););
      //if not did return / navigator or set error ='' the error will have the old error text and will show the snackBarError even if email & pw correct
     on FirebaseAuthException catch (e) 
      if (e.code == 'user-not-found') 
        er =
        'No user found for that email,this email is not exist please sign up';
       else if (e.code == 'wrong-password') 
        er = 'Wrong password provided for that user.';
      
     catch (e) 
      er = e.toString();
    
    return er;
  

  void submit() async 
    _loading = true;
    String er;
    if (!_formKey.currentState.validate()) 
      autoError = true;
      _loading = false;
      return;
    
    _formKey.currentState.save();
    if (changeAuthMode) 
      er = await signUp(er);
     else 
      er = await login(er);
    
    if (er != null) createSnackBar(er);
    setState(() 
      _loading = false;
    );
  

  @override
  void dispose() 
    emailNode.dispose();
    pNode.dispose();
    cpNode.dispose();
    _passwordController.dispose();
    super.dispose();
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      key: _scaffoldKey,
      backgroundColor: Colors.black,
      body:
        Card(
          margin: const EdgeInsets.all(30),
          shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(10)),
          child: Container(
            padding: EdgeInsets.all(16.0),
            child: Form(
              autovalidate: autoError,
              key: _formKey,
              child: SingleChildScrollView(
                child: Column(
                  children: <Widget>[
                    CustomTextForm(
                      label: 'Email',
                      inputType: TextInputType.emailAddress,
                      inputAction: TextInputAction.next,
                      node: emailNode,
                      onSubmit: (_) =>
                          FocusScope.of(context).requestFocus(pNode),
                      onSaved: (value) 
                        email = value;
                      ,
                      icon: Icon(Icons.email),
                      obscureTextVar: false,
                      validateVar: (value) 
                        if (value.isEmpty)
                          return "please enter your email";
                        RegExp pattern = new RegExp(
                            r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]1,3\.[0-9]1,3\.[0-9]1,3\.[0-9]1,3\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]2,))$');
                        if (!pattern.hasMatch(value))
                          return 'in valid email';
                        return null;
                      ,
                    ),
                    CustomTextForm(
                      label: 'password',
                      obscureTextVar: true,
                      inputType: TextInputType.visiblePassword,
                      validateVar: (value) => value.isEmpty
                          ? "please enter your password"
                          : null,
                      icon: Icon(Icons.***_key),
                      controller: _passwordController,
                      inputAction: changeAuthMode
                          ? TextInputAction.next
                          : TextInputAction.done,
                      node: pNode,
                      onSubmit: (_) 
                        changeAuthMode?
                          FocusScope.of(context).requestFocus(cpNode):
                          submit();
                      
                    ),
                    if (changeAuthMode)
                      CustomTextForm(
                        node: cpNode,
                        label: 'Conform password',
                        inputType: TextInputType.visiblePassword,
                        icon: Icon(Icons.***_key),
                        validateVar: (value) => value.isEmpty
                            ? "please enter your password"
                            : value != _passwordController.text
                            ? 'password not matches'
                            : null,
                        obscureTextVar: true,
                        inputAction: TextInputAction.done,
                        onSubmit: (_) => submit(),
                      ),
                    SizedBox(
                      height: 4,
                    ),
                    !_loading
                        ? RaisedButton(
                      color: Colors.black,
                      splashColor: Colors.white,
                      child: Text(
                          !changeAuthMode ? 'Log in' : 'sign up'),
                      onPressed: () => submit(),
                    )
                        : CircularProgressIndicator(),
                    FlatButton(
                        onPressed: changeInputState,
                        child: Text(
                            '$!changeAuthMode ? 'signUp' : 'logIn' instead')),
                  ],
                ),
              ),
            ),
          ),
        ),
    );
  

通知

我已经搜索过我的问题,我只发现这个问题看起来与我的问题非常相似,但没有解决方案。 Why can't I link firebase email-password sign-in to google sign-in?

【问题讨论】:

如果您的用户使用 Google 登录,在手动注册帐户后,由于 Firebase Authentications 受信任提供商的概念,他们的身份验证提供商将自动更改为 Google。你可以找到更多关于这个here。 一个相关的问题在这里:***.com/a/66453429/233382 【参考方案1】:

转到 Firebase 控制台身份验证 > 登录方法 > 高级 将其更改为每个电子邮件地址多个帐户..

您现在可以为不同的提供商使用相同的电子邮件地址登录

【讨论】:

【参考方案2】:

在此处查看答案和详细说明:

Firebase Auth link provider Google sign in issue?

简短的回答是可信与不可信的提供商。

【讨论】:

以上是关于为啥我无法将电子邮件/密码链接到 Firebase Flutter 中 Google 登录提供商中存在的同一电子邮件?的主要内容,如果未能解决你的问题,请参考以下文章

Firebase 无密码电子邮件身份验证无法在 iOS 上打开应用

如何将多个身份验证提供程序链接到 Firebase 帐户?

Expo App 中的 Firebase 无密码电子邮件身份验证错误

我无法登录。即使我在Firebase中输入了电子邮件和密码,它仍然会保持Saying Error Logging

Firebase忘记密码 - 如何识别用户是否使用电子邮件或Facebook登录?

无法使用正确的电子邮件地址和密码登录 Firebase