6

I have successfully implemented Firebase Google Sign-In in my android app and it works fine. But, I want the users to login into the app using email and password also. So, I followed this tutorial to link the google sign-in with email-password sign-in. But, when I try to sign-in with email-password with the following code:

firebaseAuth.signInWithEmailAndPassword(email, password)
   .addOnCompleteListener(new OnCompleteListener<AuthResult>()
   {
      @Override
      public void onComplete(@NonNull Task<AuthResult> task)
      {
         if (task.isSuccessful())
         {
             //code to link accounts
         }
         else
         {
             Toast.makeText(context, "SIgn In Error", Toast.LENGTH_SHORT).show();
             System.out.println("SIGN IN: " +  task.getException());
         }
      }
  });

It shows the exception:

com.google.firebase.auth.FirebaseAuthInvalidCredentialsException: The password is invalid or the user does not have a password.

What is wrong with the code?

eegooDeveloper
  • 395
  • 5
  • 12

2 Answers2

4

From the error message it seems like you're calling signInWithEmailAndPassword for a user that was not created yet.

You can only call signInWithEmailAndPassword(email, password) to sign in a user that was previous created with createUserWithEmailAndPassword(email, password). You explicitly can't use it to sign in a user that was previous only signed in/created with another identity provider, such as Google sign-in.

If you want to allow the same user who signed in through Google, to also sign in with a password that is specific to your app, you will need to also create those secondary credentials, and then link the two providers (Google + Email/Password).

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • so i will have to sign up another user using email-password and then link it to this google sign in? – eegooDeveloper Jul 11 '19 at 13:42
  • It's not really another user, but it's a second Firebase Authentication account yes. And then you link the two accounts together, so that signing in with one also makes them signed in with the other (and results in the same UID for their session). All of this is only needed if you want it in your app of course. – Frank van Puffelen Jul 11 '19 at 13:46
  • yeah.. I have already added google sign-in in my app. I also want to sign-in to my app using email-password with the same email as in google sign-in. I assumed that it will be possible if I link the email-password sign in with google sign-in. But, i didnt know that i will have to create a new firebase authentication using email-password for that to work.. – eegooDeveloper Jul 11 '19 at 14:30
  • Ah OK. Glad that I could clarify that then. :) – Frank van Puffelen Jul 11 '19 at 14:37
  • so, for this to work, i mean, to create two accounts with same email, i will have to change `One account per email address`, right ? – eegooDeveloper Jul 11 '19 at 14:40
  • To allow linking accounts they indeed need to use the same email address. I don't think the value of the "One account per email address" setting matters, but am not sure. – Frank van Puffelen Jul 11 '19 at 22:15
  • 1
    I dont think so. because when i tried to create email-password sign up, it showed this exception `com.google.firebase.auth.FirebaseAuthUserCollisionException: The email address is already in use by another account` – eegooDeveloper Jul 12 '19 at 04:11
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/196351/discussion-between-eegoodeveloper-and-frank-van-puffelen). – eegooDeveloper Jul 12 '19 at 04:12
-1

The same problem occur with me but i change some piece of code and it work properly.

my code are here...

/*This is th Example of google Sign in*/
import React from 'react';
import { StyleSheet, Text, View, Alert } from 'react-native';
import {
  GoogleSignin,
  GoogleSigninButton,
  statusCodes,
} from 'react-native-google-signin';
export default class GmailLogin extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      userInfo: '',
    };
  }
  componentDidMount() {
    GoogleSignin.configure({
      //It is mandatory to call this method before attempting to call signIn()
      scopes: ['https://www.googleapis.com/auth/drive.readonly'],
      // Repleace with your webClientId generated from Firebase console
      webClientId:
        'Replace Your Web Client Id here',
    });
  }
  _signIn = async () => {
    //Prompts a modal to let the user sign in into your application.
    try {
      await GoogleSignin.hasPlayServices({
        //Check if device has Google Play Services installed.
        //Always resolves to true on iOS.
        showPlayServicesUpdateDialog: true,
      });
      const userInfo = GoogleSignin.signIn();
      console.log('User Info --> ', userInfo);
      this.setState({ userInfo: userInfo });

    } catch (error) {
      console.log('Message', error.message);
      if (error.code === statusCodes.SIGN_IN_CANCELLED) {
        console.log('User Cancelled the Login Flow');
      } else if (error.code === statusCodes.IN_PROGRESS) {
        console.log('Signing In');
      } else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
        console.log('Play Services Not Available or Outdated');
      } else {
        console.log('Some Other Error Happened');
      }
    }

    this.props.navigation.navigate('Login')
  };
  _getCurrentUser = async () => {
    //May be called eg. in the componentDidMount of your main component.
    //This method returns the current user
    //if they already signed in and null otherwise.
    try {
      const userInfo = await GoogleSignin.signInSilently();
      this.setState({ userInfo });
    } catch (error) {
      console.error(error);
    }
  };
  _signOut = async () => {
    //Remove user session from the device.
    try {
      await GoogleSignin.revokeAccess();
      await GoogleSignin.signOut();
      this.setState({ user: null }); // Remove the user from your app's state as well
    } catch (error) {
      console.error(error);
    }
  };
  _revokeAccess = async () => {
    //Remove your application from the user authorized applications.
    try {
      await GoogleSignin.revokeAccess();
      console.log('deleted');
    } catch (error) {
      console.error(error);
    }
  };
  render() {
    return (
      <View style={styles.container}>
        <GoogleSigninButton
          style={{ width: 312, height: 48 }}
          size={GoogleSigninButton.Size.Wide}
          color={GoogleSigninButton.Color.Light}
          onPress={this._signIn}
        />
      </View>
    );
  }
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Add this file in setting.gradle

include ':react-native-google-signin'
project(':react-native-google-signin').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-google-signin/android')

And my MainApplication.jav code..

package com.uiapp;

import android.app.Application;

import co.apptailor.googlesignin.RNGoogleSigninPackage;

import io.invertase.firebase.RNFirebasePackage;
import io.invertase.firebase.auth.RNFirebaseAuthPackage;

import com.facebook.react.ReactApplication;
// import io.invertase.firebase.RNFirebaseAdMobPackage;
import com.smarkets.paypal.RNPaypalPackage;
import com.inprogress.reactnativeyoutube.ReactNativeYouTube;
import co.apptailor.googlesignin.RNGoogleSigninPackage;
import com.facebook.reactnative.androidsdk.FBSDKPackage;
import com.imagepicker.ImagePickerPackage;
import com.swmansion.gesturehandler.react.RNGestureHandlerPackage;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;

import com.inprogress.reactnativeyoutube.ReactNativeYouTube;

import com.smarkets.paypal.RNPaypalPackage;

import com.facebook.FacebookSdk;
import com.facebook.CallbackManager;
import com.facebook.appevents.AppEventsLogger;
import android.content.Intent;

import java.util.Arrays;
import java.util.List;

public class MainApplication extends Application implements ReactApplication {

    private static CallbackManager mCallbackManager = CallbackManager.Factory.create();
    protected static CallbackManager getCallbackManager() {
      return mCallbackManager;
    }

  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    public boolean getUseDeveloperSupport() {
      return BuildConfig.DEBUG;
    }

    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
            new MainReactPackage(),
            // new RNFirebaseAdMobPackage(),
            new RNPaypalPackage(),
            new ReactNativeYouTube(),
            new RNGoogleSigninPackage(),
            new FBSDKPackage(mCallbackManager), 
            new ImagePickerPackage(),
            new RNGestureHandlerPackage(),
            new RNFirebasePackage(),
           new RNFirebaseAuthPackage()


      );
    }

    @Override
    protected String getJSMainModuleName() {
      return "index";
    }
  };

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }

  @Override
  public void onCreate() {
    super.onCreate();
    SoLoader.init(this, /* native exopackage */ false);
  }
//   @Override
// public void onActivityResult(int requestCode, int resultCode, Intent data) {
//     super.onActivityResult(requestCode, resultCode, data);
//     MainApplication.getCallbackManager().onActivityResult(requestCode, resultCode, data);
// }

}

please dont code as some MainApplication.java code change only require place.

and paste the code in your App/android/build.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext {
        buildToolsVersion = "28.0.3"
        minSdkVersion = 16
        compileSdkVersion = 28
        targetSdkVersion = 28
        supportLibVersion = "28.0.0"
    }
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath("com.android.tools.build:gradle:3.4.0")
        classpath 'com.google.gms:google-services:4.2.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        mavenLocal()
        google()
        jcenter()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
    }
}

If you are follow these step it will solve your issue..

Abhishek Ahirwar
  • 175
  • 5
  • 15