I have been following these two tutorials:
https://developers.google.com/identity/sign-in/android/sign-in
https://developers.google.com/identity/sign-in/android/backend-auth
I managed to integrate google login system into my android application but when I try to get token id I am get null.
When I try to use following code:
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.server_client_id))
.build();
I get fail on user log in. When I call:
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
I am unable to retrieve token.
I tried to merge this code to have:
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.requestIdToken(getString(R.string.server_client_id))
.build();
but without any success.
Here is my code:
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
// [START onActivityResult]
#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);
handleSignInResult(result);
}
}
// [END onActivityResult]
// [START handleSignInResult]
private void handleSignInResult(GoogleSignInResult result) {
Log.d(TAG, "handleSignInResult:" + result.isSuccess());
if (result.isSuccess()) {
// Signed in successfully, show authenticated UI.
GoogleSignInAccount acct = result.getSignInAccount();
mStatusTextView.setText(getString(R.string.signed_in_fmt, acct.getDisplayName()));
updateUI(true);
String idToken = acct.getIdToken();
if (idToken != null) {
Log.d("TOKEN", idToken);
} else {
Log.d("TOKEN", "CHUUUUUUJ WIELKI!");
}
} else {
// Signed out, show unauthenticated UI.
updateUI(false);
}
}
Google APIs use the OAuth 2.0 protocol for authentication and
authorization. Google supports common OAuth 2.0 scenarios such as
those for web server, installed, and client-side applications.
To begin, obtain OAuth 2.0 client credentials from the Google
Developers Console. Then your client application requests an access
token from the Google Authorization Server, extracts a token from the
response, and sends the token to the Google API that you want to
access. For an interactive demonstration of using OAuth 2.0 with
Google (including the option to use your own client credentials),
experiment with the OAuth 2.0 Playground.
For details Go Through requestIdToken returning null
Related
I am new in android developement. I am developing mobile app. In this app, It is need to user country, Plz help to me, how to get user country when user sign in by google account. I am wasting much more time, but did not get any solution.
Scope myScope = new Scope("https://www.googleapis.com/auth/user.birthday.read");
Scope myScope2 = new Scope(Scopes.PLUS_ME);
Scope myScope3 = new Scope(Scopes.PROFILE); //get name and id
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestScopes(myScope, myScope2, myScope3)
.requestEmail()
.requestProfile()
.requestEmail()
.build();
mGoogleApiClient = new GoogleApiClient //this is the line of the error
.Builder(this)
.enableAutoManage(this,(GoogleApiClient.OnConnectionFailedListener) this)
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Toast.makeText(getApplicationContext(),"La conexión alcliente api de Google ha fallado",Toast.LENGTH_LONG).show();
}
})
//.addApi(Plus.API)
.addApi(Auth.GOOGLE_SIGN_IN_API,gso)
.build();
GoogleSignInAccount acct = result.getSignInAccount();
System.out.println("Display Name:="+acct.getDisplayName());
System.out.println("Display Name:="+acct.getEmail());
System.out.println(""+ acct.getGivenName());
System.out.println(""+acct.getFamilyName());
Sorry, but Shutting down Google+ and login APIs for consumer (personal) accounts on April 2, 2019
I have implemented Google Game service in my game, and I want to know if the player ID returned by Game Service can be hacked?
I will use that ID to retrieve player data from a database. I am aware that I can request ID token and use it to verify the player identity by sending it to a server and validate it there. However, requesting ID token will ask the user to allow the app to "Know who you are on Google", and I don't want to show that permission.
What you really want to use is the Server Auth Code. The flow is:
The user signs into your game on the device as normal. When you
build the client connection, request ServerAuthCode. to be
generated.
String webclientId = getString(R.string.webclient_id);
// Request authCode so we can send the code to the server.
GoogleSignInOptions options = new GoogleSignInOptions
.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
.requestServerAuthCode(webclientId)
.build();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Games.API)
.addApi(Auth.GOOGLE_SIGN_IN_API, options)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
Get the auth code when sign-in completes and send the auth code to the server.
#Override
protected void onActivityResult(int requestCode, int responseCode,
Intent intent) {
if (requestCode == RC_SIGN_IN) {
Log.d(TAG, "onActivityResult RC_SIGN_IN, responseCode="
+ responseCode + ", intent=" + intent);
GoogleSignInResult result =
Auth.GoogleSignInApi.getSignInResultFromIntent(intent);
if (result.isSuccess()) {
sendToServer(result.getSignInAccount().getServerAuthCode(););
} else {
showSignInError(result.getStatus().getStatusCode());
}
On the server exchange the auth code for an access token for that user.
GoogleTokenResponse tokenResponse =
new GoogleAuthorizationCodeTokenRequest(
HTTPTransport,
JacksonFactory.getDefaultInstance(),
"https://www.googleapis.com/oauth2/v4/token",
clientSecrets.getDetails().getClientId(),
clientSecrets.getDetails().getClientSecret(),
authCode,
"")
.execute();
The server can then verify the access token to get the user's ID
securely.
ApplicationVerifyResponse resp = gamesAPI.applications().verify
(applicationId).execute();
Log.d(TAG, "The player id is " + resp.getPlayerId());
There is a sample that shows how to do this in GitHub: https://github.com/playgameservices/clientserverskeleton
The example for using reauthenticate() in Firebase shows only how to re-authenticate a user who signed with Email and Password:
AuthCredential credential = EmailAuthProvider.getCredential("user#example.com", "password1234");
FirebaseAuth.getInstance().getCurrentUser().reauthenticate(credential);
I also know how to re-authenticate with Facebook Provider (credential = FacebookAuthProvider.getCredential(AccessToken.getCurrentAccessToken().toString())).
Problem is there's no equivelant method in Google API to get the current Access Token and eventually get the AuthCredential. So what do I pass to getCredential() in this case?
I know this is old question but I did not found complete answer to this. This is how to do it on Android.
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
// Get the account
GoogleSignInAccount acct = GoogleSignIn.getLastSignedInAccount(context);
if (acct != null) {
AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
user.reauthenticate(credential).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "Reauthenticated.");
}
}
});
}
Considering you would have received GoogleSignInResult as a response to sign-in, I think you can use the following code:
// assuming result variable has GoogleSignInResult
// GoogleSignInResult result
// Get the account
GoogleSignInAccount acct = result.getSignInAccount();
// credential
AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
FirebaseAuth.getInstance().getCurrentUser().reauthenticate(credential).addOnCompleteListener(new OnCompleteListener<Void>() {...
You can get GoogleSignInResult via 2 way to authenticate.
i) By entering email id and password into google login screen.
ii) By selecting account from already logged in account in phone.
i have used 2nd approach to get access token and authenticate user.
for more support references links are given below.
google sign in link 1
Stackoverflow - token refresh
google auth provider documentation
server side token verification docs
if your only objective is, to get token so you can also try this github source.
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
//use sign in option to build api client instence.
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
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);
handleSignInResult(result);
}
private void handleSignInResult(GoogleSignInResult result) {
Log.d(TAG, "handleSignInResult:" + result.isSuccess());
if (result.isSuccess()) {
// Signed in successfully, show authenticated UI.
GoogleSignInAccount acct = result.getSignInAccount();
} else {
// Signed out, show unauthenticated.
}
}
// get authenticated
AuthCredential credential =
GoogleAuthProvider.getCredential(acct.getIdToken(), null);
FirebaseAuth.getInstance().getCurrentUser().reauthenticate(credential)
.addOnCompleteListener(new OnCompleteListener<Void>() {
// add your job here on authenticated
}
// if token is obsoleted then you can do this
credential.refreshToken();
accessToken = credential.getAccessToken();
I am trying to find the latest solution with GoogleApiClient.Plus.API (android) for getting the email for the gplus profile. In internet, stackoverflow, every example found is obsolete and deprecated and of no use.
If it can be fetched only from Auth.GOOGLE_SIGN_IN_API then is it a two step process to fetch half of info from Auth API and rest from Plus.API ??
Thanks in advance for answer.
First I assume you have a button for google plus sign in
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.sign_in_button:
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
startActivityForResult(signInIntent, RC_SIGN_IN);
break;
}
}
At your onActivityResult you will catch sign in result
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Result returned from launching the Intent from and you can extract your user information there
if (requestCode == RC_SIGN_IN) {
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if (result.isSuccess()) {
// Signed in successfully, show authenticated UI.
GoogleSignInAccount acct = result.getSignInAccount();
//This line is your need
String yourEmail = acct.getEmail();
}
}
}
Here is how to get the email that is associated with the device, and probably with your app too:
Pattern emailPattern = Patterns.EMAIL_ADDRESS; // API level 8+
Account[] accounts = AccountManager.get(context).getAccounts();
for (Account account : accounts) {
if (emailPattern.matcher(account.name).matches()) { //If email matches the account associated with the device
String possibleEmail = account.name;
...
}
}
Let me know if this worked
After two days of struggle at last this post saved my life ..
How to get profile like gender from google signin in Android?
But the apis are obsolete, did a bit of scratch head and could make it work.
create your google api client like this
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.requestScopes(new Scope(Scopes.PLUS_LOGIN))
.build();
m_GoogleApiClient = new GoogleApiClient.Builder(m_activity)
.enableAutoManage(m_activity, this)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.addApi(Plus.API)
.build();
then on onActivityResult()
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
Log.d(TAG, "handleSignInResult:" + result.isSuccess());
if (result.isSuccess()) {
GoogleSignInAccount acct = result.getSignInAccount();
fetchConnectedProfileInfo();
}
public void fetchConnectedProfileInfo()
{
Log.d(TAG, "fetchConnectedProfileInfo");
if (m_GoogleApiClient.hasConnectedApi(Plus.API)) {
Plus.PeopleApi.load(m_GoogleApiClient, "me").setResultCallback(this);
}
}
Refer my github page for full code sample https://github.com/sandipsahoo2k2/social-login
I'm trying to get a user's profile using the new Google Sign In API introduced in play services 8.3. Other than Display Name, Email and Id, I also need user's gender.
Plus.PeopleApi.getCurrentPerson()
is deprecated as per play services 8.3 and also returns null for me even though
mGoogleApiClient.hasConnectedApi(Plus.API)
returns true.
GoogleSignInAccount.getGrantedScopes
returns
https://www.googleapis.com/auth/plus.me
https://www.googleapis.com/auth/plus.login
profile
email
openid
Google Developer Console doesn't show any hits on the Google+ API. I have placed the correct google-services.json file in app/ folder of application. I even generated the SHA1 fingerprint programatically to verify if I was using the correct keystore.
How can I get the person google+ profile data (gender, family name, given name etc.) using the new sign in API?
Plus.API has been deprecated. See deprecation notes below:
https://developers.google.com/+/mobile/android/api-deprecation
If you need profile information other than first / last / display name, email and profile picture url (which is already provided by the Sign-in API), please use the new People API.
On Android, you can do this:
// Add dependencies
compile 'com.google.api-client:google-api-client:1.22.0'
compile 'com.google.api-client:google-api-client-android:1.22.0'
compile 'com.google.apis:google-api-services-people:v1-rev4-1.22.0'
Then write sign-in code.
// Make sure your GoogleSignInOptions request profile & email
GoogleSignInOptions gso =
new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
// Follow official doc to sign-in.
// https://developers.google.com/identity/sign-in/android/sign-in
Use People Api to retrieve detailed person info.
/** Global instance of the HTTP transport. */
private static HttpTransport HTTP_TRANSPORT = AndroidHttp.newCompatibleTransport();
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
// On worker thread
GoogleAccountCredential credential =
GoogleAccountCredential.usingOAuth2(MainActivity.this, Scopes.PROFILE);
credential.setSelectedAccount(
new Account(googleSignInAccount.getEmail(), "com.google"));
People service = new People.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME /* whatever you like */)
.build();
// All the person details
Person meProfile = service.people().get("people/me").execute();
// e.g. Gender
List<Gender> genders = meProfile.getGenders();
String gender = null;
if (genders != null && genders.size() > 0) {
gender = genders.get(0).getValue();
}
UPDATE: based on #Isabella Chen's comments below, for who does not want to use getCurrentPerson which is marked deprecated, you can start using Google People API instead, you can also see my another answer at the following S.O question:
Cannot get private birthday from Google Plus account although explicit request
IMO, you can refer to the following code:
// [START configure_signin]
// Configure sign-in to request the user's ID, email address, and basic
// profile. ID and basic profile are included in DEFAULT_SIGN_IN.
// FOR PROFILE PICTURE:
// Ref: https://developers.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInAccount.html#getPhotoUrl%28%29
// getPhotoUrl(): Gets the photo url of the signed in user.
// Only non-null if requestProfile() is configured and user does have a Google+ profile picture.
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestScopes(new Scope(Scopes.PROFILE))
.requestScopes(new Scope(Scopes.PLUS_LOGIN))
.requestProfile()
.requestEmail()
.build();
// [END configure_signin]
// [START build_client]
// Build a GoogleApiClient with access to the Google Sign-In API and the
// options specified by gso.
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.addApi(Plus.API)
.build();
// [END build_client]
Then:
#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);
handleSignInResult(result);
Person person = Plus.PeopleApi.getCurrentPerson(mGoogleApiClient);
Log.i(TAG, "Gender: " + person.getGender());
}
}
Logcat info:
11-20 09:06:35.431 31289-31289/com.example.googlesignindemo I/GoogleSignIn: Gender: 0
Hope this helps!
For getting profile information google introduced the easiest way so far I think!
GoogleSignInAccount acct = GoogleSignIn.getLastSignedInAccount(getActivity());
if (acct != null) {
String personName = acct.getDisplayName();
String personGivenName = acct.getGivenName();
String personFamilyName = acct.getFamilyName();
String personEmail = acct.getEmail();
String personId = acct.getId();
Uri personPhoto = acct.getPhotoUrl();
}