如何使用FirebaseAuth从Google提供商处获得性别和生日?

时间:2017-02-23 03:49:41

标签: android firebase firebase-authentication google-signin

我尝试使用Firebase AuthUI从Google提供商那里获得性别和生日。这是我的代码。

store.dispatch(fetchAllItems([1, 2]));
console.log(store.getActions());

在onActivityResult中:

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

我得到IdpResponse idpResponse = IdpResponse.fromResultIntent(data); ,但它只包括idpResponseidpSecret。如何访问性别和生日等个人资料的其他请求字段?我可以使用

访问公共字段的电子邮件,姓名,照片等
idpToken

2 个答案:

答案 0 :(得分:7)

Firebase不支持,但你可以这样做:

首先,您需要 client_id client_secret

您可以按照以下步骤从Firebase面板中获取这两个:

身份验证>> 登录方法。点击 Google ,然后展开 Web SDK配置

Gradle依赖项:

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

在登录活动中添加以下方法。

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

获取其他详细信息的异步​​任务

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

改变你的onActivityResult如下:

@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
        }
    }

更新:如果代码出错

  

需要personFields掩码

然后使用以下代码:

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

谢谢@AbrahamGharyali。

答案 1 :(得分:1)

不幸的是,Firebase没有任何内置功能可以在成功登录后获得用户的性别/生日。您必须自己从每个提供程序中检索这些数据。

以下是使用Google People API从Google获取用户性别的方法

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

}

您可以找到有关访问Google API的更多信息