简体   繁体   中英

How to get gender and birthday from Google provider using FirebaseAuth?

I'm trying to get the gender and birthday from the Google provider using Firebase AuthUI. Here is my code.

AuthUI.IdpConfig googleIdp = new AuthUI.IdpConfig.Builder(AuthUI.GOOGLE_PROVIDER)
                .setPermissions(Arrays.asList(Scopes.EMAIL, Scopes.PROFILE, Scopes.PLUS_ME))
                .build();

startActivityForResult(
                AuthUI.getInstance().createSignInIntentBuilder()
                        .setLogo(R.drawable.firebase_auth_120dp)
                        .setProviders(Arrays.asList(
                new AuthUI.IdpConfig.Builder(AuthUI.EMAIL_PROVIDER).build(),
                googleIdp))
                        .setIsSmartLockEnabled(false)
                        .setTheme(R.style.AppTheme_Login)
                        .build(),
                RC_SIGN_IN);

In onActivityResult:

IdpResponse idpResponse = IdpResponse.fromResultIntent(data);

I got idpResponse , but it only included idpSecret and idpToken . How can I access other requested fields for profile like gender and birthday? I can access common fields email, name, photo etc with

FirebaseAuth.getInstance().getCurrentUser();

Firebase does not support that but you can do that by this way:

First you needed client_id and client_secret .

You can get these two from Firebase panel by following steps:

Authentication >> SIGN-IN METHOD . Click Google and expand Web SDK Configuration .

Gradle dependencies:

compile 'com.google.apis:google-api-services-people:v1-rev63-1.22.0'

Add following methods in your login activity.

    private void setupGoogleAdditionalDetailsLogin() {
                // Configure sign-in to request the user's ID, email address, and basic profile. ID and
                // basic profile are included in DEFAULT_SIGN_IN.
                GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                        .requestEmail()
                        .requestIdToken(GOOGLE_CLIENT_ID)
                        .requestServerAuthCode(GOOGLE_CLIENT_ID)
                        .requestScopes(new Scope("profile"))
                        .build();

        // Build a GoogleApiClient with access to GoogleSignIn.API and the options above.
                mGoogleApiClient = new GoogleApiClient.Builder(this)
                        .enableAutoManage(this, new GoogleApiClient.OnConnectionFailedListener() {
                            @Override
                            public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
                                Log.d(TAG, "onConnectionFailed: ");
                            }
                        })
                        .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
                        .build();
            }

     public void googleAdditionalDetailsResult(Intent data) {
            Log.d(TAG, "googleAdditionalDetailsResult: ");
            GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
            if (result.isSuccess()) {
                // Signed in successfully
                GoogleSignInAccount acct = result.getSignInAccount();
                // execute AsyncTask to get data from Google People API
                new GoogleAdditionalDetailsTask().execute(acct);
            } else {
                Log.d(TAG, "googleAdditionalDetailsResult: fail");
                startHomeActivity();
            }
        }

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

Async task to get additional details

public class GoogleAdditionalDetailsTask extends AsyncTask<GoogleSignInAccount, Void, Person> {
        @Override
        protected Person doInBackground(GoogleSignInAccount... googleSignInAccounts) {
            Person profile = null;
            try {
                HttpTransport httpTransport = new NetHttpTransport();
                JacksonFactory jsonFactory = JacksonFactory.getDefaultInstance();

                //Redirect URL for web based applications.
                // Can be empty too.
                String redirectUrl = "urn:ietf:wg:oauth:2.0:oob";

                // Exchange auth code for access token
                GoogleTokenResponse tokenResponse = new GoogleAuthorizationCodeTokenRequest(
                        httpTransport,
                        jsonFactory,
                        GOOGLE_CLIENT_ID,
                        GOOGLE_CLIENT_SECRET,
                        googleSignInAccounts[0].getServerAuthCode(),
                        redirectUrl
                ).execute();

                GoogleCredential credential = new GoogleCredential.Builder()
                        .setClientSecrets(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET)
                        .setTransport(httpTransport)
                        .setJsonFactory(jsonFactory)
                        .build();

                credential.setFromTokenResponse(tokenResponse);

                People peopleService = new People.Builder(httpTransport, jsonFactory, credential)
                        .setApplicationName(App.getInstance().getString(R.string.app_name))
                        .build();

                // Get the user's profile
                profile = peopleService.people().get("people/me").execute();
            } catch (IOException e) {
                Log.d(TAG, "doInBackground: " + e.getMessage());
                e.printStackTrace();
            }
            return profile;
        }

        @Override
        protected void onPostExecute(Person person) {
            if (person != null) {
                if (person.getGenders() != null && person.getGenders().size() > 0) {
                    profileGender = person.getGenders().get(0).getValue();
                }
                if (person.getBirthdays() != null && person.getBirthdays().get(0).size() > 0) {
//                    yyyy-MM-dd
                    Date dobDate = person.getBirthdays().get(0).getDate();
                    if (dobDate.getYear() != null) {
                        profileBirthday = dobDate.getYear() + "-" + dobDate.getMonth() + "-" + dobDate.getDay();
                        profileYearOfBirth = DateHelper.getYearFromGoogleDate(profileBirthday);
                    }
                }
                if (person.getBiographies() != null && person.getBiographies().size() > 0) {
                    profileAbout = person.getBiographies().get(0).getValue();
                }
                if (person.getCoverPhotos() != null && person.getCoverPhotos().size() > 0) {
                    profileCover = person.getCoverPhotos().get(0).getUrl();
                }
                Log.d(TAG, String.format("googleOnComplete: gender: %s, birthday: %s, about: %s, cover: %s", profileGender, profileBirthday, profileAbout, profileCover));
            }
            startHomeActivity();
        }
    }

Change you onActivityResult like this:

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == RC_SIGN_GOOGLE) {    // result for addition details request
            googleAdditionalDetailsResult(data);
            return;
        } else if (requestCode == RC_SIGN_IN && resultCode == RESULT_OK) {  //logged in with firebase
            if (FirebaseAuth.getInstance().getCurrentUser().getProviders().get(0).equals("google.com")) {
            // user logged in with google account using firebase ui
                startGoogleAdditionalRequest();
            } else {
            // user logged in with google
                startHomeActivity();
            }
        } else {
            // handle error
        }
    }

Update: if code gives error

personFields mask is required

then use following code:

profile = peopleService.people().get("people/me"). setRequestMaskIncludeField("person.names,person.emailAddress‌​es,person.genders,pe‌​rson.birthdays").exe‌​cute();

Thanks @AbrahamGharyali.

Unfortunately, Firebase doesn't have any built-in functionality to get the user's gender/birthdate upon successful login. You would have to retrieve these data from each of the providers yourself.

Here is how you might get the user's gender from Google using Google People API

public class SignInActivity extends AppCompatActivity implements
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener,
    View.OnClickListener {
private static final int RC_SIGN_IN = 9001;

private GoogleApiClient mGoogleApiClient;

private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;

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

    // We can only get basic information using FirebaseAuth
    mAuth = FirebaseAuth.getInstance();
    mAuthListener = new FirebaseAuth.AuthStateListener() {
        @Override
        public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
            FirebaseUser user = firebaseAuth.getCurrentUser();
            if (user != null) {
                // User is signed in to Firebase, but we can only get 
                // basic info like name, email, and profile photo url
                String name = user.getDisplayName();
                String email = user.getEmail();
                Uri photoUrl = user.getPhotoUrl();

                // Even a user's provider-specific profile information
                // only reveals basic information
                for (UserInfo profile : user.getProviderData()) {
                    // Id of the provider (ex: google.com)
                    String providerId = profile.getProviderId();
                    // UID specific to the provider
                    String profileUid = profile.getUid();
                    // Name, email address, and profile photo Url
                    String profileDisplayName = profile.getDisplayName();
                    String profileEmail = profile.getEmail();
                    Uri profilePhotoUrl = profile.getPhotoUrl();
                }
            } else {
                // User is signed out of Firebase
            }
        }
    };

    // Google sign-in button listener
    findViewById(R.id.google_sign_in_button).setOnClickListener(this);

    // Configure GoogleSignInOptions
    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(getString(R.string.server_client_id))
            .requestServerAuthCode(getString(R.string.server_client_id))
            .requestEmail()
            .requestScopes(new Scope(PeopleScopes.USERINFO_PROFILE))
            .build();

    // Build a GoogleApiClient with access to the Google Sign-In API and the
    // options specified by gso.
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .enableAutoManage(this, this)
            .addOnConnectionFailedListener(this)
            .addConnectionCallbacks(this)
            .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
            .build();
}

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

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);

    // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
    if (requestCode == RC_SIGN_IN) {
        GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
        if (result.isSuccess()) {
            // Signed in successfully
            GoogleSignInAccount acct = result.getSignInAccount();

            // execute AsyncTask to get gender from Google People API
            new GetGendersTask().execute(acct);

            // Google Sign In was successful, authenticate with Firebase
            firebaseAuthWithGoogle(acct);
        }
    }
}

class GetGendersTask extends AsyncTask<GoogleSignInAccount, Void, List<Gender>> {
    @Override
    protected List<Gender> doInBackground(GoogleSignInAccount... googleSignInAccounts) {
        List<Gender> genderList = new ArrayList<>();
        try {
            HttpTransport httpTransport = new NetHttpTransport();
            JacksonFactory jsonFactory = JacksonFactory.getDefaultInstance();

            //Redirect URL for web based applications.
            // Can be empty too.
            String redirectUrl = "urn:ietf:wg:oauth:2.0:oob";

            // Exchange auth code for access token
            GoogleTokenResponse tokenResponse = new GoogleAuthorizationCodeTokenRequest(
                    httpTransport,
                    jsonFactory,
                    getApplicationContext().getString(R.string.server_client_id),
                    getApplicationContext().getString(R.string.server_client_secret),
                    googleSignInAccounts[0].getServerAuthCode(),
                    redirectUrl
            ).execute();

            GoogleCredential credential = new GoogleCredential.Builder()
                    .setClientSecrets(
                        getApplicationContext().getString(R.string.server_client_id), 
                        getApplicationContext().getString(R.string.server_client_secret)
                    )
                    .setTransport(httpTransport)
                    .setJsonFactory(jsonFactory)
                    .build();

            credential.setFromTokenResponse(tokenResponse);

            People peopleService = new People.Builder(httpTransport, jsonFactory, credential)
                    .setApplicationName("My Application Name")
                    .build();

            // Get the user's profile
            Person profile = peopleService.people().get("people/me").execute();
            genderList.addAll(profile.getGenders());
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        return genderList;
    }

    @Override
    protected void onPostExecute(List<Gender> genders) {
        super.onPostExecute(genders);
        // iterate through the list of Genders to
        // get the gender value (male, female, other)
        for (Gender gender : genders) {
            String genderValue = gender.getValue();
        }
    }
}

}

You can find more information on Accessing Google APIs

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