问题
I use OAuth to let users sign in to the android app via Google account. When the user taps the Google login button for the first time, it produces a dialog to choose the account. Again, when the user logs out and decides to login with different Google account, it doesn't prompt to choose the account, it logs in the account the user had chose the previous time
'
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
initialize();
Firebase.setAndroidContext(this);
ref=new Firebase("https://texter10c.firebaseio.com");
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
progressDialog.setMessage("Logging in !");
progressDialog.setTitle("Hang on!");
progressDialog.show();
ref.authWithPassword(emailField.getText().toString(), passwordField.getText().toString(), new Firebase.AuthResultHandler() {
@Override
public void onAuthenticated(AuthData authData) {
Log.e("Authenticated","Authenticated");
getUserIdandLogin();
}
@Override
public void onAuthenticationError(FirebaseError firebaseError) {
progressDialog.dismiss();
Toast.makeText(LoginActivity.this, firebaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
});
signupButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(LoginActivity.this, SignupActivity.class);
startActivity(intent);
}
});
googleSignInButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
progressDialog.setTitle("Contacting Google");
progressDialog.setMessage("Logging you in");
progressDialog.show();
if(!mGoogleApiClient.isConnected())
mGoogleApiClient.connect();
}
});
}
private void getGoogleToken(){
AsyncTask<Void,Void,String> task=new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... params) {
final String scopes="oauth2:"+"https://www.googleapis.com/auth/plus.login"+" "+"https://www.googleapis.com/auth/plus.me";
try {
if(!mGoogleApiClient.isConnected())
{
mGoogleApiClient.connect();
}
googleAccessToken= GoogleAuthUtil.getToken(LoginActivity.this,Plus.AccountApi.getAccountName(mGoogleApiClient),scopes);
Log.e("AccessToken",googleAccessToken+"");
}
catch (IOException e)
{
e.printStackTrace();
}
catch (GoogleAuthException e)
{
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
try {
ref.authWithOAuthToken("google", googleAccessToken, new Firebase.AuthResultHandler() {
@Override
public void onAuthenticated(final AuthData authData) {
try {
Log.e("Firebase", "Google Authentication Success");
Log.e("Username", authData.getProviderData().get("displayName").toString());
Log.e("Id", authData.getProviderData().get("id").toString());
Firebase googleUserRef = ref.child("UserDetails/names/" + authData.getProviderData().get("id").toString());
Map<String, String> googleUserMap = new HashMap<String, String>();
googleUserMap.put("Username", authData.getProviderData().get("displayName").toString());
final String UserID = "GoogleUser" + authData.getProviderData().get("displayName") + authData.getProviderData().get("id");
googleUserMap.put("UserId", UserID);
googleUserRef.setValue(googleUserMap, new Firebase.CompletionListener() {
@Override
public void onComplete(FirebaseError firebaseError, Firebase firebase) {
progressDialog.dismiss();
dataStore.setCurrentUserName(authData.getProviderData().get("displayName").toString());
dataStore.setCurrentUserID(UserID);
storeDatainSharedPreferences();
Intent intent = new Intent(LoginActivity.this, DialogActivity.class);
startActivity(intent);
}
});
}
catch (NullPointerException e)
{
e.printStackTrace();
}
}
@Override
public void onAuthenticationError(FirebaseError firebaseError) {
Log.e("GogoleAuthFailed", firebaseError.getMessage());
}
});
}
catch (NullPointerException e)
{
Log.e("Accesstoken problem",e.getMessage());
}
}
};
task.execute();
}
public void getUserIdandLogin()
{
dataStore.userDialogMap=new ArrayList<Map<String,String>>();
dataStore.generatedChatIds=new ArrayList<>();
Firebase refUser=ref.child("UserDetails/names");
refUser.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Map<String, String> map = new HashMap<String, String>();
map = dataSnapshot.getValue(Map.class);
try{
if (map.get("Email").equals(emailField.getText().toString()))
{
Toast.makeText(LoginActivity.this, "Successfilly Logged in", Toast.LENGTH_SHORT).show();
dataStore.setCurrentUserName(map.get("Username"));
dataStore.setCurrentUserID(map.get("UserId"));
intent=new Intent(LoginActivity.this,DialogActivity.class);
startActivity(intent);
storeDatainSharedPreferences();
progressDialog.dismiss();
}
}
catch (NullPointerException e)
{
Log.e("NullPointerGUser",e.getMessage());
}
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(FirebaseError firebaseError) {
}
});
}
private void storeDatainSharedPreferences() {
try {
SharedPreferences.Editor editor = getSharedPreferences(NEW_PREFS, MODE_PRIVATE).edit();
editor.putString("CurrentUsername", dataStore.getCurrentUserName());
editor.putString("CurrentUserId", dataStore.getCurrentUserID());
editor.commit();
}
catch (NoSuchElementException e)
{
new AlertDialog.Builder(LoginActivity.this).setMessage("There was an error whil logging in")
.setTitle("Little Problem here!").setPositiveButton("Retry", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent=new Intent(LoginActivity.this,LoginActivity.class);
removeDatainSharedPreferences();
mGoogleApiClient.disconnect();
startActivity(intent);
}
}).show();
}
}
private void removeDatainSharedPreferences() {
SharedPreferences.Editor editor = getSharedPreferences(NEW_PREFS, MODE_PRIVATE).edit();
editor.remove("CurrentUsername");
editor.remove("CurrentUserId");
editor.commit();
}
private void initialize() {
emailInputLayout=(TextInputLayout)findViewById(R.id.emailInputLayout);
emailField=(EditText)findViewById(R.id.emailField);
passwordField=(EditText)findViewById(R.id.passwordField);
passwordInputLayout=(TextInputLayout)findViewById(R.id.passwordInputLayout);
loginButton=(Button)findViewById(R.id.loginButton);
emailInputLayout.setHint("Email");
passwordInputLayout.setHint("Password");
progressDialog=new ProgressDialog(LoginActivity.this);
signupButton=(TextView)findViewById(R.id.signupButton);
forgotPasswordButton=(TextView)findViewById(R.id.forgotPasswordField);
googleSignInButton=(SignInButton)findViewById(R.id.googleSignInButton);
googleSignInButton.setColorScheme(SignInButton.COLOR_AUTO);
forgotPasswordButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(LoginActivity.this,ForgotPasswordActivity.class);
startActivity(intent);
}
});
SharedPreferences sharePreferences=getSharedPreferences(NEW_PREFS,MODE_PRIVATE);
if(!sharePreferences.getString("CurrentUsername","null").equals("null")) {
Log.e("SharedPreferences", sharePreferences.getString("CurrentUsername", "null"));
Log.e("SharedPreferences",sharePreferences.getString("CurrentUserId",null));
Intent intent=new Intent(LoginActivity.this,DialogActivity.class);
startActivity(intent);
}
mGoogleApiClient=new GoogleApiClient.Builder(this)
.addApi(Plus.API)
.addScope(Plus.SCOPE_PLUS_LOGIN)
.addScope(Plus.SCOPE_PLUS_PROFILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
if(!isNetworkAvailable())
{
snackbar=Snackbar.make(findViewById(android.R.id.content),"You are offline",Snackbar.LENGTH_INDEFINITE)
.setAction("Retry", new View.OnClickListener() {
@Override
public void onClick(View v) {
if(!isNetworkAvailable())
dismissSnackBar();
else
snackbar.show();
}
});
snackbar.show();
}
}
private void dismissSnackBar() {
snackbar.dismiss();
}
private boolean isNetworkAvailable()
{
ConnectivityManager manager=(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkIngo=manager.getActiveNetworkInfo();
return networkIngo!=null&& networkIngo.isConnected();
}
@Override
public void onConnected(@Nullable Bundle bundle) {
Log.e("GoogleApi","Connected");
getGoogleToken();
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.e("GoogleApi",connectionResult.toString());
if(!connectionResult.hasResolution())
{
GooglePlayServicesUtil.getErrorDialog(connectionResult.getErrorCode(),LoginActivity.this,0).show();
}
if(connectionResult.isSuccess())
{
getGoogleToken();
}
try
{
connectionResult.startResolutionForResult(this,100);
}
catch (IntentSender.SendIntentException e)
{
e.printStackTrace();
}
}
}
`
回答1:
Just add this signIn() method after getting data from the intent.
Intent signInIntent=Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
mGoogleApiClient.clearDefaultAccountAndReconnect();
回答2:
The simplest way is to logout the client after you handle your result (onActivityResult). Just make sure that the client is connected before you trigger the logout. Here's a snippet of my code:
private void handleGoogleLoginResult(Intent data) {
if (data != null) {
// get result from data received
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
int statusCode = result.getStatus().getStatusCode();
if (result.isSuccess() && result.getSignInAccount() != null) {
// Signed in successfully
}
// logout
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
Auth.GoogleSignInApi.signOut(mGoogleApiClient);
}
}
}
回答3:
You needed to log out the user from google client.
public void signOut() {
mAuth.signOut();
mGoogleSignInClient.signOut();
LoginManager.getInstance().logOut();
}
Where
private FirebaseAuth mAuth;
private GoogleSignInClient mGoogleSignInClient;
and
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
mAuth = FirebaseAuth.getInstance();
回答4:
Simplely workout for me
1>Activity implements GoogleApiClient.OnConnectionFailedListener {
2>
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
3>In OnButtonClicked
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
startActivityForResult(signInIntent, 2);
4>
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 2) {
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if (result.isSuccess()) {
GoogleSignInAccount acct = result.getSignInAccount();
if(acct!=null) {
//Take all data You Want
String identifier = acct.getId()+"";
String displayName = acct.getDisplayName()+"";
//After You got your data add this to clear the priviously selected mail
mGoogleApiClient.clearDefaultAccountAndReconnect();
}
}else Log.e("handleSignInResult","Failed ; "+result.getStatus());
}
}
回答5:
Those who needs it in kotlin, this worked for me, I do clear current login cache before a new login request is made
/**
* signInGoogle
*/
private fun signInGoogle() = launch{
//init google sigin
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(GOOGLE_WEBCLIENT_ID)
.requestEmail()
.build()
val gApiClient = GoogleApiClient.Builder(activity)
.addApi(Auth.GOOGLE_SIGN_IN_API,gso)
.build()
val c = gApiClient.blockingConnect()
if(c.isSuccess && gApiClient.isConnected){
gApiClient.clearDefaultAccountAndReconnect().await()
}
val mGoogleSignInClient = GoogleSignIn.getClient(activity, gso)
val signInIntent = mGoogleSignInClient.signInIntent
//start activit
startActivityForResult(signInIntent, GOOGLE_SIGNIN)
}//end request google login
You can view the full source here : https://github.com/transcodium/TNSMoney-Android/blob/master/app/src/main/java/com/transcodium/tnsmoney/SocialLoginActivity.kt
回答6:
Signout your user using:
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
// ...
}
});
回答7:
I found this question while searching for a solution using the javascript client, but it might be similar with Android.
signIn({ prompt: 'select_account' })
select_account
The authorization server prompts the user to select a Google account. This allows a user who has multiple accounts to select amongst the multiple accounts that they may have current sessions for.
See https://developers.google.com/identity/sign-in/web/reference#googleauthsigninoptions.
回答8:
You are not revoking user by sign out them use the following to achieve what you need :
Put this code in any activity and call it in sign out button click :
private void signOut() {
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
// ...
}
});
}
write this in onCreate() :
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API)
.build();
override this in onStart() :
@Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
Reference Link : Google Developer Page
回答9:
I am using the Firebase Auth UI, and For me the fix was;
AuthUI.getInstance().setIsSmartLockEnabled(false)...
When logging in, and then;
AuthUI.signOut(context)
When Signing out
回答10:
This is worked for me. !!
@Override
public void onPause() {
super.onPause();
if (mGoogleApiClient.isConnected()) {
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
// ...
}
});
}
mGoogleApiClient.stopAutoManage(Objects.requireNonNull(getActivity()));
mGoogleApiClient.disconnect();
}
if you want to enter again within the Fragment or Activity , you need to recreate these variables
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
mGoogleApiClient = new GoogleApiClient.Builder(Objects.requireNonNull(getActivity()))
.enableAutoManage(getActivity(), (this))
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
回答11:
If you are having any logout functionality. Put the below code just before your logout code:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
CookieManager.getInstance().removeAllCookies(null);
CookieManager.getInstance().flush();
}
else
{
CookieSyncManager cookieSyncMngr=CookieSyncManager.createInstance(activity);
cookieSyncMngr.startSync();
CookieManager cookieManager=CookieManager.getInstance();
cookieManager.removeAllCookie();
cookieManager.removeSessionCookie();
cookieSyncMngr.stopSync();
cookieSyncMngr.sync();
}
Hope this will help.
EDIT: you can also try replacing you
storeDatainSharedPreferencesmethod with below code:
private void storeDatainSharedPreferences() {
try {
SharedPreferences.Editor editor = getSharedPreferences(NEW_PREFS, MODE_PRIVATE).edit();
editor.putString("CurrentUsername", dataStore.getCurrentUserName());
editor.putString("CurrentUserId", dataStore.getCurrentUserID());
editor.commit();
if(mGoogleApiClient!=null)
mGoogleApiClient.disconnect();
}
catch (NoSuchElementException e)
{
new AlertDialog.Builder(LoginActivity.this).setMessage("There was an error whil logging in")
.setTitle("Little Problem here!").setPositiveButton("Retry", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent=new Intent(LoginActivity.this,LoginActivity.class);
removeDatainSharedPreferences();
mGoogleApiClient.disconnect();
startActivity(intent);
}
}).show();
}}
Explanation : For First solution : It is the code to clear all Cookies related to your application. This can be help full in your situation because you want to clear the previous data which might be stored in Cookies.
Explanation : For Second solution : It is the code which disconnects the mGoogleApiClient. which will be helpful because You have stored the data in sharedPref now you don't need
mGoogleApiClient.
来源:https://stackoverflow.com/questions/36659753/google-login-uses-same-account-everytime-users-login