2

I developped an application that uses gmail api to get all the mails from the user. Then I divided this app in a sample (almost empty) and a fragment that does everything, so I can later integrate my fragment easily in my team's project's settings.

Now that my fragment is in the other project, the gmail connexion doesn't work and gives me these errors :

E/Async Task: com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAuthIOException
E/Google log in: failed

I think this error is because the project uses firebase and already have a google-services.json file and mine isn't used. We added the GMail API in the google developper portal and generated a new json file but it doesn't seem to work.

Why does my GMail connexion fails and how can I solve it ?

Hamid Asghari
  • 5,751
  • 4
  • 24
  • 34
Diiscord
  • 101
  • 1
  • 7

2 Answers2

1

Ok, I managed to get it working.

Looks like when I create credentials keys in the API manager Google console, it doesn't add the SHA1 keys in all the apps of the project in Firebase.

All I had to do (after a week of hard work) was to copy paste the SHA1 from tha app "linked" to the Google API console in the other app

I hope it can help

Diiscord
  • 101
  • 1
  • 7
0

Use this code to integrate gmail login using firebase . If already login it will navigate to homeScreen and if not logined previously it will pop up email to login once sign in clicked.

Add you server_client_id in string.xml used here :

getString(R.string.server_client_id)

Code :

MainActivity.java

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.auth.api.signin.GoogleSignInResult;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.GoogleAuthProvider;
import smart.works.android.bharat.com.codeplay.ui.homeScreen.CodePlayActivity;
import smart.works.android.bharat.com.codeplay.R;
import smart.works.android.bharat.com.codeplay.Utils.AppConstants;
import smart.works.android.bharat.com.codeplay.Utils.PreferenceUtils;

public class MainActivity extends AppCompatActivity
    implements GoogleApiClient.OnConnectionFailedListener, View.OnClickListener {

  private static final int RC_SIGN_IN = 124;
  private static final String TAG = "MainActivity";
  private GoogleApiClient mGoogleApiClient;
  private FirebaseAuth mAuth;
  private ProgressBar mProgressBar;
  private SignInButton mSignInButton;

  @Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    initUi();
    setupUi();
  }

  private void setupUi() {
    GoogleSignInOptions gso =
        new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).requestIdToken(
            getString(R.string.server_client_id)).requestEmail().build();
    mGoogleApiClient =
        new GoogleApiClient.Builder(this).enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
            .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
            .build();
    // Set the dimensions of the sign-in button.
    mSignInButton = (SignInButton) findViewById(R.id.sign_in_button);
    mSignInButton.setSize(SignInButton.SIZE_STANDARD);
    findViewById(R.id.sign_in_button).setOnClickListener(this);
    mAuth = FirebaseAuth.getInstance();
  }

  private void initUi() {
    mProgressBar = (ProgressBar) findViewById(R.id.sign_in_progress);
    mSignInButton = (SignInButton) findViewById(R.id.sign_in_button);
  }

  @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

  }

  @Override public void onClick(View v) {
    switch (v.getId()) {
      case R.id.sign_in_button:
        signIn();
        break;
    }
  }

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

  private void showProgress() {
    mProgressBar.setVisibility(View.VISIBLE);
    mSignInButton.setEnabled(false);
  }

  private void cancelProgress() {
    mProgressBar.setVisibility(View.GONE);
    mSignInButton.setEnabled(true);
  }

  @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) {
      showProgress();
      GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
      handleSignInResult(result);
    }
  }

  private void handleSignInResult(GoogleSignInResult result) {
    Log.d(TAG, "handleSignInResult:" + result.isSuccess());
    if (result.isSuccess()) {
      // Google Sign In was successful, authenticate with Firebase
      GoogleSignInAccount account = result.getSignInAccount();
      firebaseAuthWithGoogle(account);

      //updateUI(true);
    } else {
      cancelProgress();
      Toast.makeText(MainActivity.this, "sign in failed ! Try Again ", Toast.LENGTH_SHORT).show();
      // Signed out, show unauthenticated UI.
      //updateUI(false);
    }
  }

  @Override public void onStart() {
    super.onStart();
    // Check if user is signed in (non-null) and update UI accordingly.
    FirebaseUser currentUser = mAuth.getCurrentUser();
    if (currentUser != null) {
      forwardToHomeScreen(currentUser);
    }

    //updateUI(currentUser);

  }


  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) {
            cancelProgress();
            if (task.isSuccessful()) {
              // Sign in success, update UI with the signed-in user's information
              Log.d(TAG, "signInWithCredential:success");
              FirebaseUser user = mAuth.getCurrentUser();
              forwardToHomeScreen(user);
            } else {
              // If sign in fails, display a message to the user.
              Log.w(TAG, "signInWithCredential:failure", task.getException());
              Toast.makeText(MainActivity.this, "Authentication failed.", Toast.LENGTH_SHORT)
                  .show();
              //updateUI(null);
            }

            // ...
          }
        });
  }

  private void forwardToHomeScreen(FirebaseUser user) {
    PreferenceUtils preferenceUtils = new PreferenceUtils(this);
    preferenceUtils.getPrefEditor().putString(AppConstants.USER_ID, user.getUid()).apply();
    Intent i = new Intent(this, CodePlayActivity.class);
    i.putExtra(AppConstants.USER_NAME, user.getDisplayName());
    i.putExtra(AppConstants.USER_EMAIL, user.getEmail());
    i.setData(user.getPhotoUrl());
    startActivity(i);
    finish();
  }
}

actvity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/nav_bg"
    android:orientation="vertical"
    >

  <ImageView
      android:id="@+id/icon"
      android:layout_width="100dp"
      android:layout_height="100dp"
      android:layout_alignParentTop="true"
      android:layout_centerInParent="true"
      android:layout_marginTop="100dp"
      android:contentDescription="@string/app_icon"
      android:src="@mipmap/ic_launcher"
      />
  <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_below="@+id/icon"
      android:layout_centerInParent="true"
      android:layout_marginBottom="60dp"
      android:text="@string/app_name"
      android:textColor="#FFFFFF"
      android:textSize="16sp"
      android:textStyle="bold"
      />
  <ProgressBar
      android:id="@+id/sign_in_progress"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_centerInParent="true"
      android:indeterminate="true"
      android:visibility="gone"
      />
  <com.google.android.gms.common.SignInButton
      android:id="@+id/sign_in_button"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentBottom="true"
      android:layout_centerInParent="true"
      android:layout_marginBottom="100dp"
      />


</RelativeLayout>
Elysian Apps
  • 106
  • 3
  • This doesn't really answer my question. So all the code I've made in my first app can't be used in a Firebase app ? And my fragment is supposed to work in both apps, so should I switch all my authentication code to the firebase authentication and then integrate firebase in my application ? – Diiscord Jul 18 '17 at 08:52
  • You don't need to change your previous authenticaton code if its working fine . In your handleSignInResult() method when you get result success then go for firebaseAuthWithGoogle(GoogleSignInAccount acct) method . see my code . Use your latest google_services.json . Enable Gmail API in Api console . Also add your debug and released SHA1 in API . Only debug SHA1 also works during development – Elysian Apps Jul 18 '17 at 18:42
  • Thank you for your answers, the problem is that I don't have handleSignInResult method and a GoogleSignInAccount. I used this quickstart https://developers.google.com/gmail/api/quickstart/android so I have a GoogleAccountCredential – Diiscord Jul 19 '17 at 09:03
  • I think if you get auth token then you can use firebaseAuthWithGoogle(..) .You should be able to call the method getToken() on the GoogleAccountCredential object and use that token to create AuthCredential object and do mAuth.signInWithCredential(credential) . See this SO ans you will get more detailed insight. https://stackoverflow.com/a/22335286/8321236 – Elysian Apps Jul 19 '17 at 13:22