Merging of Providers
Tags: flutter, dart
Published: 2019-12-14 02:56:38

# Hello developers :clap: 

### It's fishy when it comes to merging between the account merging between Google and Facebook. <{:heart:}>

### What's the issue ??  <{:heart:}>
- When signing in with Google, generally all the applications directly allow you to sign-in with your account.
- ex: When you sign-in with an email ex: hello_world@gmail.com
- Let's suppose you have the same email address you use for facebook, when you try signing-in with facebook, it fails with an exception that   "ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL", this is because the primary email is always Google for any platform you consider.
- In this case, the dart platform provides an efficient tool called LinkWithCredientials


### Here is the dart code for Google authentication <{:heart:}>

````dart
    final GoogleSignInAccount googleSignInAccount =
          await googleSignIn.signIn();
      final GoogleSignInAuthentication googleSignInAuthentication =
          await googleSignInAccount.authentication;
      googleCredential = GoogleAuthProvider.getCredential(
        accessToken: googleSignInAuthentication.accessToken,
        idToken: googleSignInAuthentication.idToken,
      );
      detail = await GlobalVariables.firebaseAuth
          .signInWithCredential(googleCredential);
````

### Here is the dart code for Facebook authentication <{:heart:}>

````dart
final result = await facebookLogin
          .logIn(['email', 'public_profile', 'user_friends']);
      switch (result.status) {
        case FacebookLoginStatus.error:
          break;
        case FacebookLoginStatus.cancelledByUser:
          break;
        case FacebookLoginStatus.loggedIn:
          final token = result.accessToken.token;
          final graphResponse = await http.get(
              'https://graph.facebook.com/v2.12/me?fields=name,picture.width(800).height(800),first_name,last_name,email&access_token=$token');
          final profile = await json.decode(graphResponse.body);

          facebookCredential =
              FacebookAuthProvider.getCredential(accessToken: token);
          GlobalVariables.firebaseUser =
              await GlobalVariables.firebaseAuth.currentUser();
          try {
           details = await GlobalVariables.firebaseAuth
                .signInWithCredential(facebookCredential);
````

- Now the above code throws an exception if the account has already been signed in with Google. To overcome this error use the try-catch block and embed the code inside it. Now when the exception is caught by try-catch use the code to check if the exception is the same as I have mentioned above, and use the proper creds.


````dart
catchError((onError) {
              if (onError.code ==
                  "ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL") {
                              GlobalVariables.firebaseAuth
                    .fetchSignInMethodsForEmail(email: profile['email'])
                    .then((data) async {
                  final GoogleSignInAccount googleSignInAccount =
                      await googleSignIn.signIn();
                  final GoogleSignInAuthentication googleSignInAuthentication =
                      await googleSignInAccount.authentication;
                  googleCredential = GoogleAuthProvider.getCredential(
                    accessToken: googleSignInAuthentication.accessToken,
                    idToken: googleSignInAuthentication.idToken,
                  );
                  GlobalVariables.firebaseAuth
                      .signInWithCredential(googleCredential).then((data) {
                    var user = data.user;
                    user.linkWithCredential(facebookCredential);
            }
});
````
` Now this will link the user directly to Google(or any other providers of your choice).

### This is the simple solution. Though the documentation of firebase says it all, practically they have not shown it for the dart.