3
votes

I am playing around with Google Plus Authentication and Firebase.

I am working through the basic auth example with Android at the moment. The basic authentication part is working fine with the code on github, and it works as it should. https://github.com/firebase/firebase-login-demo-android

The problem now arises when I am trying to fetch the email address, for some reason it doesn't seem to exist in the authData object.

From the Firebase documentation on Google authentication:

getProviderData().get("email") - The Google user's primary email address as listed on their profile. Returned only if a valid email address is available, and the Google email permission was granted by the user.

If I add a textview in activity_main.xml ..... .....

Then in my code MainActivity.java:

private void setAuthenticatedUser(AuthData authData) {
    if (authData != null) {
    /* Hide all the login buttons */
    ......
    mLoggedInStatusTextView.setVisibility(View.VISIBLE);
    mEmailTextView = (TextView) findViewById(R.id.email_textView);
    mEmailTextView.setText(authData.getProviderData().get("email").toString());
    mEmailTextView.setVisibility(View.VISIBLE);
    ......
}

I get an error: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference

Additionally, in Android Studion with Debug on, when I look into the authData object, email is not set, but other values are - auth, provider, providerData, token, uid, expires, etc...

Everything seems to be working great except fetching the email address. I'm not sure if any addiontial permissions are needed. In my AndroidManifest.xml file I have the following:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />

From what I've read, the GET_ACCOUNTS permission SHOULD be enough. Any ideas on why Firebase can't seem to fetch it?

EDIT: Additionally, I am able to save my user data to Firebase https://www.firebase.com/docs/android/guide/user-auth.html#section-storing

if(authData.getProviderData().containsKey("email")) {
    map.put("displayName", authData.getProviderData().get("email").toString());
}

Then this email value is always empty, so it's not retrieving the email from Google Plus at all.

5

5 Answers

1
votes

It sounds like you need to request an additional scope that includes email. If you add that scope, you'll be able to access email with getProviderData().

Why

Google+ Sign-in for Android requests a default set of scopes. This set does not include email by default.

How

The scopes are defined when you initialize your GoogleApiClient, as documented here. Specify the email scope.

mGoogleApiClient = new GoogleApiClient.Builder(this)
    .addConnectionCallbacks(this)
    .addOnConnectionFailedListener(this)
    .addApi(Plus.API)
    .addScope(Plus.SCOPE_PLUS_LOGIN)
    .addScope("email") // <-- This requests the email address
    .build();

The docs also contain a list of commonly used Google+ Sign-In scopes.

1
votes

I've run into this problem this week. Even by adding the needed scopes, I was still unable to access to the user's email. The authData callback always had the same fields no matter what scope I added.

I've tried .addScope(new Scope("email")) and .addScope(new Scope("https://www.googleapis.com/auth/plus.profile.emails.read")) but achieved nothing.

The only way I managed to retrieve the user's email was by using the Google's onConnected method and asking by the user's email there.

if (Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null) {
        String email = Plus.AccountApi.getAccountName(mGoogleApiClient);
        Log.i("email", email);
    }
0
votes

you can use a different method other than getProviderData().get("email") to get user email.

String email = Plus.AccountApi.getAccountName(mGoogleApiClient);

This should get user email address. <uses-permission android:name="android.permission.GET_ACCOUNTS" /> is sufficient for permission so you don't need to add any permission or scope.

0
votes

You can get user's email from the Plus object like this:

if (mGoogleApiClient.isConnected()) {
    String email = Plus.AccountApi.getAccountName(mGoogleApiClient);
}
0
votes

You can fetch Firebase User email by Firebase Auth Service.

 FirebaseAuth.AuthStateListener mAuthListener = new FirebaseAuth.AuthStateListener() {
        @Override
        public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
            FirebaseUser user = firebaseAuth.getCurrentUser();
            if (user != null) {
              String email = user.getEmail();
            }
        }
    };