为什么我能';是否将电子邮件/密码链接到firebase Flatter中的google登录提供商中存在的相同电子邮件?

为什么我能';是否将电子邮件/密码链接到firebase Flatter中的google登录提供商中存在的相同电子邮件?,firebase,flutter,firebase-authentication,google-signin,Firebase,Flutter,Firebase Authentication,Google Signin,我曾与firebase auth的谷歌登录和电子邮件/密码提供商合作过,我注意到在我与电子邮件/密码提供商注册后,我可以使用相同的电子邮件使用谷歌登录和电子邮件/密码提供商,也可以在注册电子邮件后注销,这样我就可以以我的身份进入authscreen,但是,当我使用谷歌登录并从谷歌注销并尝试注册后,用另一个帐户尝试反向登录时,给我错误电子邮件已经存在当我尝试登录时给我错误密码是错误的即使我写的谷歌电子邮件密码100%正确,那么,有没有一种方法可以启用签名 选择代码\u提供程序\u屏幕

我曾与firebase auth的谷歌登录和电子邮件/密码提供商合作过,我注意到在我与电子邮件/密码提供商注册后,我可以使用相同的电子邮件使用谷歌登录和电子邮件/密码提供商,也可以在注册电子邮件后注销,这样我就可以以我的身份进入authscreen,但是,当我使用谷歌登录并从谷歌注销并尝试注册后,用另一个帐户尝试反向登录时,给我错误电子邮件已经存在当我尝试登录时给我错误密码是错误的即使我写的谷歌电子邮件密码100%正确,那么,有没有一种方法可以启用签名



选择代码\u提供程序\u屏幕

  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:firebase_auth/firebase_auth.dart';
进口“包装:颤振/材料.省道”;
导入“package:flatter_app/tabs.dart”;
导入“./signinologin_Screen.dart”;
导入“包:google_sign_in/google_sign_in.dart”;
未来登录使用Google()异步{
final GoogleSignInAccount googleuser=等待GoogleSignIn().signIn();
最终GoogleSignInAuthentication googleauth=等待googleuser.authentication;
最终GoogleAuthCredential凭证=GoogleAuthProvider.credential(
accessToken:googleauth.accessToken,
idToken:googleauth.idToken,
);
返回wait wait FirebaseAuth.instance.signInWithCredential(凭证);
}
小部件createRaised(
{颜色背景颜色,
字符串图像,
字符串名,
颜色文本颜色,
函数f}){
返回大小框(
宽度:290,
子:RaisedButton.icon(
按:f,
标签:文本(
名称
样式:TextStyle(字体大小:18,颜色:textcolor),
),
图标:填充(
填充:仅限常量边集(右:10),
子:Image.asset(
形象,,
身高:20,
fit:BoxFit.fill,
),
),
填充:边缘设置。全部(10),
形状:圆形矩形边框(
边界半径:边界半径。圆形(30),
边:边框边(颜色:Colors.black)),
颜色:背景色,
splashColor:Colors.transparent,
highlightColor:Colors.transparent,
),
);
}
类ChoiceAuthMehod扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(),
正文:中(
子:列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
大小盒子(
宽度:290,
孩子:升起按钮(
颜色:颜色,黑色,
子:文本(
“注册/登录”,
样式:TextStyle(颜色:Colors.red,字体大小:18),
),
已按下:(){
导航器(上下文)
.pushReplacementName(AuthScreen.routeName);
},
填充:边缘设置。全部(10),
形状:圆形矩形边框(
边界半径:边界半径。圆形(30),
边:边框边(颜色:Colors.black)),
),
),
大小盒子(
身高:10,
),
创造提高(
背景颜色:Colors.white,
图片:“lib/google_transperant.png”,
姓名:'与谷歌注册',
f:()=>使用Google()登录。然后((值){
打印('email google:${value.user.displayName}');
导航器(上下文)
.pushReplacementNamed(Tabs.routeName);
}),
text颜色:颜色。黑色),
],
),
),
);
}
}

登录代码
导入“包装:颤振/材料.省道”;
导入“包:firebase_auth/firebase_auth.dart”;
导入“package:flatter_app/checkuserstate.dart”;
导入“./textfiledform.dart”;
类AuthScreen扩展StatefulWidget{
静态常量routeName='/Auth screen';
@凌驾
_AuthScreenState createState()=>\u AuthScreenState();
}

class _AuthScreenState扩展状态

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


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

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


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

如果您的用户在手动注册帐户后登录Google,他们的身份验证提供商将自动更改为Google,因为Firebase身份验证是受信任提供商的概念。您可以了解更多信息。如果您的用户在手动注册帐户后登录Google,他们的身份验证提供商将自动更改为Google,因为Firebase身份验证概念是可信提供商。你可以找到更多关于这个的信息。
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.vpn_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.vpn_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')),
                  ],
                ),
              ),
            ),
          ),
        ),
    );
  }
}