I am trying to get the user's information, including gender and age, from its Google Plus account. Since these fields may be private, I thought that requesting them explicitly would solve the problem. However, although the sign in dialog states explicitly that the app requests to View your complete date of birth
, I fail to get the birthday.
These are my scopes (tried many variations):
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
//.requestScopes(new Scope(Scopes.PROFILE))
//.requestScopes(new Scope(Scopes.PLUS_LOGIN))
.requestScopes(new Scope("https://www.googleapis.com/auth/user.birthday.read"),
new Scope("https://www.googleapis.com/auth/userinfo.profile"))
//.requestProfile()
.requestEmail()
.build();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this, this)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.addApi(Plus.API)
.addScope(new Scope(Scopes.PROFILE))
.build();
When using the deprecated getCurrentPerson
in onActivityResult
, I get null value:
if (requestCode == RC_SIGN_IN) {
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if (mGoogleApiClient.hasConnectedApi(Plus.API)) {
Person person = Plus.PeopleApi.getCurrentPerson(mGoogleApiClient);
if (person != null) {
Log.i(TAG, person.getDisplayName()); //returns full name successfully
Log.i(TAG, person.getGender()); //0
Log.i(TAG, person.getBirthday()); //null
}
}
}
I also tried to get it from the account (GoogleSignInAccount account = result.getSignInAccount()
) but as far as I've searched, this variable doesn't own the requested data at all.
Am I missing something? Or maybe it's impossible to get private data although explicit request?
Thanks.
BTW, I haven't tried yet a scenario with a private gender.
I think this Google People API documentation will be helpful for your issue.
Please pay attention to:
If the request requires authorization (such as a request for an individual's private data), then the application must provide an OAuth 2.0 token with the request. The application may also provide the API key, but it doesn't have to.
and
Requests to the People API for non-public user data must be authorized by an authenticated user.
...
- If the user approves, then Google gives your application a short-lived access token.
- Your application requests user data, attaching the access token to the request.
- If Google determines that your request and the token are valid, it returns the requested data.
If your app has not got an access token, you can read Using OAuth 2.0 to Access Google APIs or try my answer at the following question:
How to get access token after user is signed in from Gmail in Android?
UPDATE: Supposing that your app can get the access token by using the sample code in my answer above, then inside onResponse
, add more snippets as below:
...
@Override
public void onResponse(Response response) throws IOException {
try {
JSONObject jsonObject = new JSONObject(response.body().string());
final String message = jsonObject.toString(5);
Log.i("onResponse", message);
// FROM HERE...
String accessToken = jsonObject.optString("access_token");
OkHttpClient client2 = new OkHttpClient();
final Request request2 = new Request.Builder()
.url("https://people.googleapis.com/v1/people/me")
.addHeader("Authorization", "Bearer " + accessToken)
.build();
client2.newCall(request2).enqueue(new Callback() {
@Override
public void onFailure(final Request request, final IOException e) {
Log.e("onFailure", e.toString());
}
@Override
public void onResponse(Response response) throws IOException {
try {
JSONObject jsonObject = new JSONObject(response.body().string());
final String message = jsonObject.toString(5);
Log.i("onResponse", message);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
...
Logcat info (I truncated since it's long)
I/onResponse: {
"photos": [
{
"url": "https:...photo.jpg",
"metadata": {
"source": {
"id": "1....774",
"type": "PROFILE"
},
"primary": true
}
}
],
...
"birthdays": [
{
"date": {
"month": 2,
"year": 1980,
"day": 2
},
"metadata": {
"source": {
"id": "1....774",
"type": "PROFILE"
},
"primary": true
}
}
],
....
}
GoogleSignInOptions
and GoogleApiClient
:
String serverClientId = getString(R.string.server_client_id);
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestScopes(new Scope("https://www.googleapis.com/auth/user.birthday.read"))
.requestServerAuthCode(serverClientId)
.build();
GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
Please note that the OkHttp version I use here is v2.6.0, if your app uses the newest (3.3.1), then the syntax/classes will be different. Of course, you can also use the others such as Volley, Retrofit...
Moreover, this Google's People API - Method people.get provides Try It as screenshot below
Other useful links:
Google Developers Blog - Announcing the People API
Google APIs related to Google People API
Authorizing with Google for REST APIs (another way to get access token)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With