简体   繁体   中英

Android Firebase Authentication for Google Signin fails

I followed the firebase documentation from top to bottom and implemented a simple google Sign in option to my app. However, when I try to signin, the process halts after selecting a google account and results in an error inside the onActivityResult method:

if (requestCode == RC_SIGN_IN) {
       GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
       if (result.isSuccess()) {
            // Google Sign In was successful, authenticate with Firebase
            GoogleSignInAccount account = result.getSignInAccount();
            firebaseAuthWithGoogle(account);
       } else {
            //THE CODE BREAKS HERE
            // Google Sign In failed, update UI appropriately
       }
}

The code breaks at the if (result.isSuccess()) condition. To elaborate further, here's the complete code I implemented after going through the doc:

onCreate:

public class TestLogin extends AppCompatActivity {

    private SignInButton mGoogleBtn;
    private static int RC_SIGN_IN = 226;
    private GoogleApiClient mGoogleApiClient;
    private  String TAG = "Checkmate";
    private FirebaseAuth mAuth;
    private FirebaseAuth.AuthStateListener mAuthListener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test_login);

        mAuth = FirebaseAuth.getInstance();
        mAuthListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                if(firebaseAuth.getCurrentUser() != null){
                    //success
                }
            }
        };

        mGoogleBtn = (SignInButton) findViewById(R.id.googleBtn);

        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestIdToken("MY_CLIENT_ID-MY_CLIENT_ID.apps.googleusercontent.com")
                .requestEmail()
                .build();

        mGoogleApiClient = new GoogleApiClient.Builder(getApplicationContext())
                .enableAutoManage(this, new GoogleApiClient.OnConnectionFailedListener() {
                    @Override
                    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
                        //Failed
                    }
                })
                .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
                .build();

        mGoogleBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                statusMessage.setText("Loading..");
                signIn();
            }
        });
    }

signIn method:

The SignIn method gets called when the Google Signin button is clicked :

    private void signIn() {
        Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
        startActivityForResult(signInIntent, RC_SIGN_IN);
    }

onActivityResult:

onActivityResult is called when the result is received after clicking the button. This is where the error occurs:

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
        if (requestCode == RC_SIGN_IN) {
            GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
            if (result.isSuccess()) {
                // Google Sign In was successful, authenticate with Firebase
                GoogleSignInAccount account = result.getSignInAccount();
                firebaseAuthWithGoogle(account);
            } else {
                //THE CODE BREAKS HERE
                // Google Sign In failed, update UI appropriately
            }
        }
    }

Handling Firebase Login code for Google:

This method never gets called because the code breaks at the onActivityResult condition.

    private void firebaseAuthWithGoogle(final GoogleSignInAccount acct) {

        AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
        mAuth.signInWithCredential(credential)
                .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {

                        // If sign in fails, display a message to the user. If sign in succeeds
                        // the auth state listener will be notified and logic to handle the
                        // signed in user can be handled in the listener.
                        if (!task.isSuccessful()) {
                            Toast.makeText(TestLogin.this, "Authentication failed.",
                                    Toast.LENGTH_SHORT).show();
                        }
                    }
                });
    }

    @Override
    protected void onStart() {
        super.onStart();
        mAuth.addAuthStateListener(mAuthListener);
    }

Checklist :

Yes, I added the google_services.json file to the /app directory

Yes, I created a new OAuth Client Key in the Google Credentials page

Here's my gradle:

dependencies {
    compile 'com.google.android.gms:play-services:9.6.1'
    compile 'com.google.firebase:firebase-core:9.6.1'
    compile 'com.google.firebase:firebase-database:9.6.1'
    compile 'com.google.firebase:firebase-auth:9.6.1'
    compile 'com.google.firebase:firebase-storage:9.6.1'
}
apply plugin: 'com.google.gms.google-services'

And..

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.3'
        classpath 'com.google.gms:google-services:3.0.0'
    }
}

In my previous test app using Firebase FriendlyChat, I have encountered similar failure in Sign In, but I have solved it by going Google API console ( https://console.developers.google.com/apis/credentials?project= ) then download "client_secret.json" (in my case, I need to rename the downloaded filename "client_secret_xxxxx.json") for your Android client, put this file in your AndroidStudio project under "/src/main/resources" (create "resources" folder if not exist) then try to compile and run your Android app again.

Summary: you need 2 json files : "google-services.json" from Firebase Console and "client_secret.json" from Google API Console.

Hope this solve your problem.

检查是否在Google API控制台中启用了“Identity Toolkit API”

Go to the firebase console and enable the sign in provider first. https://console.firebase.google.com/u/2/project/ipay-71f01/authentication/providers

I had the same issue but this was the solution for me. Thanks

Make sure that you have entered the SHA1 of your signing keystore. Here's the guide https://developers.google.com/android/guides/client-auth

You have to find two directories, 1. a directory where JDK have been installed 2. .android

If you are using Windows, '.android' folder might be placed in 'C:\\Users\\username\\', and JDK directory might be placed in like 'C:\\Users\\Program files\\java\\'.

In my case, my OS is Windows, so first i was looking for my jdk folder.

In 'jdk_folder\\bin\\' you would find 'keytool.exe' and I used this command

'.\\keytool -exportcert -list -v -alias androiddebugkey -keystore C:\\Users\\sgc109\\ .android\\debug.keystore'.

Then, copy SHA1 key and paste to firebase console(setting - general - my app - SHA certificate finger print(?)' (I live in Korea, so names of menu could be different with me) and it works :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM