Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recent changes with Firebase Authentication via. Google Sign-In?

I've a question to people who use Firebase Google Sign-In authentication:

My app, which has already been working for a couple of months, is using both Google Sign-In and e-mail/password options for Firebase Authentication. However about a week ago I've noticed that the Google Sign-In stopped working. No code was changed, also the e-mail/password option works just as usual.

I've checked the documentation (https://firebase.google.com/docs/auth/android/google-signin), it's still the same (My app copies the authentication method from the documentation).

Did you face a similar problem too? If yes, please tell me how can I solve it.

Here is my code related to Google Sign-in inside my LoginActivity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    ...   
    //--------Google Sign In
    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(getString(R.string.default_web_client_id))
            .requestEmail()
            .build();

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .enableAutoManage(this, new GoogleApiClient.OnConnectionFailedListener() {
                @Override
                public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
                    Toast.makeText(LoginActivity.this, "Connection failed!", Toast.LENGTH_SHORT).show();
                }
            })
            .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
            .build();

    mGoogleBttn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            SignIn();
        }
    });

}

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

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    mProgress.setMessage("Signing in with Google Account...");
    mProgress.show();
    // 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 {
            // Google Sign In failed, update UI appropriately
            // ...
            mProgress.dismiss();
            Toast.makeText(LoginActivity.this, "Google sign in failed!", Toast.LENGTH_SHORT).show();
        }
    }
}

private void firebaseAuthWithGoogle(GoogleSignInAccount acct) {
    Log.d(TAG, "firebaseAuthWithGoogle:" + acct.getId());

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

                    mProgress.dismiss();
                    checkUserExist();

                    // 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()) {
                        Log.w(TAG, "signInWithCredential", task.getException());
                        Toast.makeText(LoginActivity.this, "Authentication failed.",
                                Toast.LENGTH_SHORT).show();
                    }
                }
            });
}

private void checkUserExist() {
    final String user_id = mAuth.getCurrentUser().getUid();
    mDatabaseUsers.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.hasChild(user_id)) {
                Intent mainIntent = new Intent(LoginActivity.this, MainActivity.class);
                mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(mainIntent);
            } else {
                Intent setupIntent = new Intent(LoginActivity.this, SetupActivity.class);
                setupIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(setupIntent);
            }
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });
}

Here are my app and project level build.gradle files: https://gist.github.com/anonymous/2c9737e898ca2568129af63e61a30f16

like image 472
Sergei Emelianov Avatar asked Jan 01 '26 16:01

Sergei Emelianov


1 Answers

As OP has found the solution to the problem and answered it already. I'll be trying to explain the cases, as requested by OP, that might be the real causes behind the problem. Before that lets know something about keystores and certificates.

The documentation says:

Android requires that all APKs be digitally signed with a public-key certificate before they can be installed. Even that application you build and run during the development period must be signed with a certificate. If you don't do it manually Android Studio automatically signs your APK with a debug certificate generated by the Android SDK tools. The first time you run or debug your project in Android Studio, the IDE automatically creates the debug keystore and certificate in $HOME/.android/debug.keystore, and sets the keystore and key passwords. A public-key certificate, also known as a digital certificate or an identity certificate, contains the public key of a public/private key pair, as well as some other metadata identifying the owner of the key (for example, name and location). The owner of the certificate holds the corresponding private key.

When you sign an APK, the signing tool attaches the public-key certificate to the APK. The public-key certificate serves as as a "fingerprint" that uniquely associates the APK to you and your corresponding private key. This helps Android ensure that any future updates to your APK are authentic and come from the original author.

A keystore is a binary file that contains one or more private keys.

Every app must use the same certificate throughout its lifespan in order for users to be able to install new versions as updates to the app.

Back to the question; after studying the OP's problem and with a short conversation with him I came up with following deduction:

  • He must be using one keystore/certificate for development and different certificate for Project Setting(firebase console).
  • Since, Google Sign-In was working fine for a couple of months but stopped lately, he must have changed the keystore lately.
  • Found that he has just migrated to new development device and hence the app he build now might have a new debug keystore file and new certificate which shall be, in fact, different from that in Project Setting.

The case is still a mystery, I later knew that the OP never built or ran his app from the new device.

P.S. Android Studio automatically creates the debug keystore and certificate in $HOME/.android/debug.keystore, and sets the keystore and key passwords the first time you run or debug your project. This mean that every computer you work on will generate a new SHA-1 unless you have a copy of a previous keystore file and you use it.

like image 100
Niraj Niroula Avatar answered Jan 03 '26 05:01

Niraj Niroula



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!