How to re-authenticate a user on Firebase with Google Provider? - android

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

Related

GoogleSignIn.getLastSignedInAccount() returns null on release build

I'm trying to add google sign-in to my android app. Everything works fine on debug build. But when I push the apk for internal testing on Google Play it throws Google SignIn API Exception 10. Should I add anything extra to my console?
So far I've done the following things,
Created new firebase project
Added SHA-1 to firebase console.
Downloaded google-services.json from firebase and copied to app
folder.
On my https://console.cloud.google.com/apis/credentials
page everything is automatically filled by firebase. So, I didn’t do
anything there.
Add all required libraries to android project
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
SignInButton signInButton = findViewById(R.id.sign_in_button);
signInButton.setSize(SignInButton.SIZE_WIDE);
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
mGoogleSignInClient = GoogleSignIn.getClient(this, so);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Result returned from launching the Intent from GoogleSignInClient.getSignInIntent(...);
if (requestCode == RC_SIGN_IN) {
// The Task returned from this call is always completed, no need to attach
// a listener.
// Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
try {
// Google Sign In was successful, authenticate with Firebase
GoogleSignInAccount account = task.getResult(ApiException.class);
Log.e(TAG, "firebaseAuthWithGoogle:" + account.getId());
//firebaseAuthWithGoogle(account.getIdToken());
} catch (ApiException e) {
// Google Sign In failed, update UI appropriately
Log.e(TAG, "Google sign in failed", e);
}
handleSignInResult(task);
}
}
HandleSignInResult;
private void handleSignInResult(Task<GoogleSignInAccount>
completedTask) {
String personName = "", personEmail = "", aid = "";
Uri personPhoto = Uri.parse("");
// GoogleSignInAccount acct =
GoogleSignIn.getLastSignedInAccount(this);
GoogleSignInAccount acct = completedTask.getResult();
if (acct != null) {
personName = acct.getDisplayName();
personEmail = acct.getEmail();
personPhoto = acct.getPhotoUrl();
aid = acct.getId();
Log.e("ID_TOKEN", acct.getIdToken() + "");
}
}
It's now working after I added the SHA-1 from Google Play console under Release -> Setup -> App integrity as #lasagnakid77 mentioned in his comment.

Google signin Issue in Android

I am trying to signin user with google.
I got the demo code to login, and it is working fine.
Scenario 1: User Login with already existing account.
expected solution: after user selected his/her account, and in onActivityResult i should get the details of the selected email account like, name, pic, email etc etc..... and this is coming correct.
Scenario 2: User can add new account and logged in auatomatically.
Expected solution: When user clicks on signin with google, and selected create new account instead of selecting already existing account. the user will go to the add new account page and insert their credentials, and after successfully adding new account, user should automatically login.
Error : But when user adds new account and comes back to the login page. I am able to get the email, id but givenName, and familyName is null. I need the name of the user.
Now the account is added in the device, next when user select the newly added account from login page, at that time in onActivityResult i am getting the NAME of the user.
What i want is when user adds a new account or select an existing account, it should show me the name of the user
Here is the code to handleSignIn
LoginActivity.java
public void onStart() {
super.onStart();
OptionalPendingResult<GoogleSignInResult> opr = Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient);
if (opr.isDone()) {
// If the user's cached credentials are valid, the OptionalPendingResult will be "done"
// and the GoogleSignInResult will be available instantly.
Log.d(TAG, "Got cached sign-in");
GoogleSignInResult result = opr.get();
handleSignInResult(result);
} else {
// If the user has not previously signed in on this device or the sign-in has expired,
// this asynchronous branch will attempt to sign in the user silently. Cross-device
// single sign-on will occur in this branch.
opr.setResultCallback(new ResultCallback<GoogleSignInResult>() {
#Override
public void onResult(GoogleSignInResult googleSignInResult) {
handleSignInResult(googleSignInResult);
}
});
}
}
#Override
protected void onCreate(Bundle savedInstanceState){
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();
}
protected void onActivityResult(
final int requestCode,
final int resultCode,
final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
handleSignInResult(result);
} else
callbackManager.onActivityResult(requestCode, resultCode, data);
}
private void handleSignInResult(GoogleSignInResult result) {
Log.d(TAG, "handleSignInResult:" + result.isSuccess());
if (result.isSuccess()) {
// Signed in successfully, show authenticated UI.
GoogleSignInAccount acct = result.getSignInAccount();
Log.e(TAG, "handleSignInResult: getPhotoUrl " + acct.getPhotoUrl());
Log.e(TAG, "handleSignInResult: getServerAuthCode " + acct.getServerAuthCode());
Log.e(TAG, "handleSignInResult: getIdToken " + acct.getIdToken());
Log.e(TAG, "handleSignInResult: getId " + acct.getId());
Log.e(TAG, "handleSignInResult: getGivenName " + acct.getGivenName()); //firstName and lastName=""
Log.e(TAG, "handleSignInResult: getDisplayName " + acct.getDisplayName());
Log.e(TAG, "handleSignInResult: getEmail " + acct.getEmail());
Log.e(TAG, "handleSignInResult: getFamilyName " + acct.getFamilyName());
Log.e(TAG, "handleSignInResult: getAccount " + acct.getAccount());
Set<Scope> scopeSet = acct.getGrantedScopes();
for (Scope scope : scopeSet) {
Log.e(TAG, "handleSignInResult: " + scope.zzpp());
}
}
}
I added this code
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.requestIdToken("Web client (auto created by Google Service)") // added this line
.requestProfile()
.build();
Web client is found at https://console.developers.google.com and go to you app.
Select Credentials at left and you will find Web Client in OAuth 2.0 client IDs section.

User profile info null in Firebase Auth with Google Sign-In

How can I get the name and profile photo of a Google account from a FirebaseUser?
I'm following Firebase's Android documentation on integrating Google Sign-In and Firebase Authentication. When I authenticate with Google Sign-In, I can get user profile information from GoogleSignInAccount#getPhotUrl() and GoogleSignInAccount#getDisplayName().
I can sign in to Firebase with FirebaseAuth.getInstance().signInWithCredential(account) (where account is the same authenticated GoogleSignInAccount object. But I get null values for the user profile information from the Firebase side.
Google Sign-In result callback:
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if (result.isSuccess()) {
GoogleSignInAccount account = result.getSignInAccount();
account.getEmail(); // Valid email
account.getDisplayName(); // Valid name
account.getPhotoUrl(); // Valid Uri
firebaseAuthWithGoogle(account);
}
Google Sign-In + Firebase Auth:
private void firebaseAuthWithGoogle(GoogleSignInAccount account) {
AuthCredential credential = GoogleAuthProvider.getCredential(account.getIdToken(), null);
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// Sign in success, update UI with the signed-in user's information
Log.d(TAG, "signInWithCredential:success");
FirebaseUser user = mAuth.getCurrentUser();
user.getEmail(); // Valid email
user.getDisplayName(); // null
user.getPhotoUrl(); // null
}
}
});
}
I was able to fix my problem by using a new Firebase project and new Gmail account.

how to retrieve email from gplus using android

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

Android get google token id

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

Categories

Resources