I have LoginActivity with Email/password login, facebook, google authentication. It works separately but if I create account with google, I can't login with facebook.
Login activity code:
public class LoginActivity extends AppCompatActivity {
private Button mLogin,mRegister;
private int RC_SIGN_IN =0;
private EditText mEmail, mPassword;
public FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener firebaseAuthStateListener;
CallbackManager callbackManager;
private LoginButton loginButton;
private static final String EMAIL = "email";
private TextView facebookRegister;
private SignInButton googleSignIn;
GoogleSignInClient mGoogleSignInClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
Intent intent = new Intent(LoginActivity.this, LoginTest.class);
startActivity(intent);
//FACEBOOK
mAuth = FirebaseAuth.getInstance();
FacebookSdk.sdkInitialize(getApplicationContext());
AppEventsLogger.activateApp(getApplication());
callbackManager = CallbackManager.Factory.create();
// 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)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
// Build a GoogleSignInClient with the options specified by gso.
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
googleSignIn = findViewById(R.id.sign_in_button);
googleSignIn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.sign_in_button:
signIn();
break;
// ...
}
}
});
firebaseAuthStateListener= new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if(user !=null){
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();
return;
}
}
};
loginButton = findViewById(R.id.login_button);
loginButton.setReadPermissions(Arrays.asList(EMAIL));
mLogin = (Button) findViewById(R.id.login);
mEmail = (EditText) findViewById(R.id.email);
mPassword=(EditText) findViewById(R.id.password);
mRegister=(Button)findViewById(R.id.register);
// Callback registration
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
// App code
handleFacebookToken(loginResult.getAccessToken());
//fill database
}
#Override
public void onCancel() {
// App code
}
#Override
public void onError(FacebookException exception) {
// App code
}
});
mLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
logInEmailPassword();
}
});
mRegister.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(LoginActivity.this, RegistrationActivity.class);
startActivity(intent);
finish();
return;
}
});
}
#Override
protected void onStart() {
super.onStart();
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
mAuth.addAuthStateListener(firebaseAuthStateListener);
}
#Override
protected void onStop() {
super.onStop();
mAuth.removeAuthStateListener(firebaseAuthStateListener);
}
private void logInEmailPassword() {
String email = mEmail.getText().toString();
String password = mPassword.getText().toString();
if(email.isEmpty()){
Toast.makeText(LoginActivity.this, "Wrong email", Toast.LENGTH_SHORT).show();
mEmail.setError("Enter email!");
};
if(password.isEmpty()){
mPassword.setError("Enter password!");
Toast.makeText(LoginActivity.this, "Wrong password", Toast.LENGTH_SHORT).show();
}
if(!email.isEmpty() && !password.isEmpty()){
AuthCredential credential = EmailAuthProvider.getCredential(email, password);
linkWithCredential(credential);
}
}
private void handleFacebookToken(AccessToken token) {
AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken());
linkWithCredential(credential);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.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);
handleSignInResult(task);
}
}
private void signIn() {
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
startActivityForResult(signInIntent, RC_SIGN_IN);
}
private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
try {
GoogleSignInAccount account = completedTask.getResult(ApiException.class);
FirebaseGoogleAuth(account);
// Signed in successfully, show authenticated UI.
} catch (ApiException e) {
// The ApiException status code indicates the detailed failure reason.
// Please refer to the GoogleSignInStatusCodes class reference for more information.
Log.w("myLog", "signInResult:failed code=" + e.getStatusCode());;
}
}
private void FirebaseGoogleAuth(GoogleSignInAccount account) {
AuthCredential authCredential = GoogleAuthProvider.getCredential(account.getIdToken(),null);
linkWithCredential(authCredential);
}
private void linkWithCredential(AuthCredential credential){
mAuth = FirebaseAuth.getInstance()
//mAuth.getCurrentUser().linkWithCredential(credential)
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Log.d("myLog", "linkWithCredential:success");
FirebaseUser user = task.getResult().getUser();
updateUI(user);
} else {
Log.w("myLog", "linkWithCredential:failure", task.getException());
Toast.makeText(LoginActivity.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
LoginManager.getInstance().logOut();
updateUI(null);
}
// ...
}
});
}
}
I've followed https://firebase.google.com/docs/auth/android/account-linking?authuser=0 tutorial but I stuck at linkWithCredential.
Can you help me fix that issue? Thanks
The problem if that user exists in Firebase Authentication already and is assigned to GoogleAuth i cant login with Facebook.
It works vice versa, if facebook user exists in firebase and i login with google it overrides that user.
Register ---- logout ---- login
Google --->>>>>>>>>>>>>>>>Facebook >>>>dont work
Facebook--->>>>>>>>>>>>>>>Google >>>>> works
Related
I have a LoginActivity where user signs in to my app via Firebase (sign in with Google). How to access and update the signed-in user's details in other activity. Also how to sign out the user in the next or other activity.
LoginActivity.java
public class LoginActivity extends AppCompatActivity {
private SignInButton signInButton;
private GoogleSignInClient googleSignInClient;
private String TAG = "Login Activity";
private FirebaseAuth auth;
private int RC_SIGN_IN = 1;
SharedPreferences sp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
signInButton = findViewById(R.id.btnSignInGoogle);
auth = FirebaseAuth.getInstance();
sp = getSharedPreferences("login", MODE_PRIVATE);
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
if (sp.getBoolean("logged",false)){
gotoMainActivity();
}else {
googleSignInClient = GoogleSignIn.getClient(this, gso);
signInButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
signin();
}
});
}
}
private void signin() {
Intent signInIntent = googleSignInClient.getSignInIntent();
startActivityForResult(signInIntent, RC_SIGN_IN);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN){
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
handleSignInResult(task);
}
}
private void handleSignInResult(Task<GoogleSignInAccount> completedTask){
try {
GoogleSignInAccount acc = completedTask.getResult(ApiException.class);
//Signed In Successfully
FirebaseGoogleAuth(acc);
} catch (ApiException e) {
e.printStackTrace();
//Sign In Failed
FirebaseGoogleAuth(null);
}
}
private void FirebaseGoogleAuth(final GoogleSignInAccount acct) { //To handle firebase google authentication
AuthCredential authCredential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
auth.signInWithCredential(authCredential).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) { //checking authentication credential and checking successful or not
if (task.isSuccessful()) {
// Success
FirebaseUser user = auth.getCurrentUser();
updateUI(user);
} else {
// Fail
updateUI(null);
}
}
});
}
private void updateUI(FirebaseUser fuser) {
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(getApplicationContext());
if (account != null){
gotoMainActivity();
sp.edit().putBoolean("logged", true).apply();
}
}
private void gotoMainActivity() {
Intent intent = new Intent(this,MainActivity.class);
startActivity(intent);
}}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private FirebaseUser user;
Button btnSignOut;
TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnSignOut = findViewById(R.id.btnSignInGoogle);
textView = findViewById(R.id.textView);
user = FirebaseAuth.getInstance().getCurrentUser();
btnSignOut.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
user.signout();
}
});
}}
I want to sign out the user in MainActivity. And I want to access and update all the details about the user in MainActivity and other activities in the future.
I want to sign out the user in MainActivity.
You can not call signout() on a FirebaseUser object, you should call it on a FirebaseAuth object like this:
FirebaseAuth.getInstance().signout();
And I want to access and update all the details about the user in MainActivityand other activities in the future.
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String uid = user.getUid();
if(user != null) {
Map<String, Object> updates = new HashMap<>();
updates.put("fieldName", "fieldData");
FirebaseFirestore.getInstance().collection("users").document(uid).update(updates);
}
In this way you can update a field name of type String in user document in Cloud Firestore.
I have integrated Google authenticate login in my app but after once login if I log out my account still every time app automatically sign in the old user account.
MainAcivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
GoogleSignInClient mGoogleSignInClient;
private FirebaseAuth mAuth;
private int RC_SIGN_IN=1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAuth = FirebaseAuth.getInstance();
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
if (account != null){
String personName = account.getDisplayName();
String personGivenName = account.getGivenName();
String personFamilyName = account.getFamilyName();
String personEmail = account.getEmail();
String personId = account.getId();
Uri personPhoto = account.getPhotoUrl();
Intent i=new Intent(MainActivity.this,Welcome.class);
i.putExtra("pn",personName);
i.putExtra("pe",personEmail);
startActivity(i);
}
findViewById(R.id.sign_in_button).setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.sign_in_button:
signIn();
break;
// ...
}
}
private void signIn() {
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
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 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);
handleSignInResult(task);
}
}
private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
try {
GoogleSignInAccount account = completedTask.getResult(ApiException.class);
// Signed in successfully, show authenticated UI.
Intent i=new Intent(MainActivity.this,Welcome.class);
startActivity(i);
} catch (ApiException e) {
// The ApiException status code indicates the detailed failure reason.
// Please refer to the GoogleSignInStatusCodes class reference for more information.
Log.w("SignInFailed", "signInResult:failed code=" + e.getStatusCode());
Toast.makeText(MainActivity.this,"SignInFailed",Toast.LENGTH_SHORT).show();
}
}
}
Welcome Acivity
public class Welcome extends AppCompatActivity {
TextView textView,textView2;
GoogleSignInClient mGoogleSignInClient;
private GoogleApiClient mGoogleApiClient;
private FirebaseAuth mAuth;
Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
textView=findViewById(R.id.textView);
textView2=findViewById(R.id.textView2);
button=findViewById(R.id.button);
Intent iin= getIntent();
Bundle b = iin.getExtras();
if(b!=null)
{
String j =(String) b.get("pn");
textView.setText(j);
String k =(String) b.get("pe");
textView2.setText(k);
}
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
if(account == null){
Intent i=new Intent(Welcome.this,MainActivity.class);
startActivity(i);
}
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
signOut();
}
});
}
private void signOut() {
mGoogleSignInClient.signOut()
.addOnCompleteListener(this, new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Intent i=new Intent(Welcome.this,MainActivity.class);
startActivity(i);
}
});
}
//
}
I have used google docs about sign out but I can't solve my problem. I haven't found any useful questions from already asked by others.
I appreciate any help you folks can offer.
You also need to sign out from GoogleSignInClient and FirebaseAuth current user, something like this:
//sign out of the user and start login activity.
public void signOut() {
signOutBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
GoogleSignInClient mGoogleSignInClient = GoogleSignIn.getClient(getContext(), gso);
mGoogleSignInClient.signOut();
FirebaseAuth.getInstance().signOut();
startActivity(new Intent(getContext(), LoginActivity.class));
}
});
}
I am trying to keep the user logged into my chat app even after they close the app. So the only way they will be logged out of their account is if they click the log out button.
So far the user does stayed logged in but when I click the log out button, the app crashes. This is the error I get
Attempt to invoke virtual method 'java.lang.String com.google.firebase.auth.FirebaseUser.getUid()' on a null object reference
at com.example.chatterbox.ChatsFragment.onCreateView(ChatsFragment.java:54)
the problem is that that error is from a different file. Can someone please help me ?
public class LoginActivity extends AppCompatActivity {
private FirebaseAuth mAuth;
private ProgressDialog loadingBar;
private Button LoginButton ;
private EditText UserEmail, UserPassword;
private TextView NeedNewAccountLink, ForgetPasswordLink;
private DatabaseReference UsersRef;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
RelativeLayout relativeLayout = findViewById(R.id.layout);
AnimationDrawable animationDrawable = (AnimationDrawable) relativeLayout.getBackground();
animationDrawable.setEnterFadeDuration(5000);
animationDrawable.setExitFadeDuration(5000);
animationDrawable.start();
mAuth = FirebaseAuth.getInstance();
UsersRef = FirebaseDatabase.getInstance().getReference().child("Users");
InitializeFields();
if (UsersRef != null) {
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
NeedNewAccountLink.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SendUserToRegisterActivity();
}
});
LoginButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AllowUserToLogin();
}
});
}
private void AllowUserToLogin () {
String email = UserEmail.getText().toString();
String password = UserPassword.getText().toString();
if (TextUtils.isEmpty(email)) {
Toast.makeText(this, "Please enter your email", Toast.LENGTH_SHORT).show();
}
if (TextUtils.isEmpty(password)) {
Toast.makeText(this, "Please enter your password", Toast.LENGTH_SHORT).show();
} else {
loadingBar.setTitle("Logging In");
loadingBar.setMessage("Please wait...");
loadingBar.setCanceledOnTouchOutside(true);
loadingBar.show();
mAuth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
String currentUserId = mAuth.getCurrentUser().getUid();
String deviceToken = FirebaseInstanceId.getInstance().getToken();
UsersRef.child(currentUserId).child("device_token")
.setValue(deviceToken)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
SendUserToMainActivity();
Toast.makeText(LoginActivity.this, "Logged in successfully", Toast.LENGTH_SHORT).show();
loadingBar.dismiss();
}
}
});
} else {
String message = task.getException().toString();
Toast.makeText(LoginActivity.this, "Error:" + message, Toast.LENGTH_SHORT).show();
loadingBar.dismiss();
}
}
});
}
}
private void InitializeFields () {
LoginButton = (Button) findViewById(R.id.login_button);
UserEmail = (EditText) findViewById(R.id.login_email);
UserPassword = (EditText) findViewById(R.id.login_password);
NeedNewAccountLink = (TextView) findViewById(R.id.need_new_account_link);
ForgetPasswordLink = (TextView) findViewById(R.id.forget_password_link);
loadingBar = new ProgressDialog(this);
}
private void SendUserToMainActivity () {
Intent mainIntent = new Intent(LoginActivity.this, MainActivity.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(mainIntent);
finish();
}
private void SendUserToRegisterActivity () {
Intent registerIntent = new Intent(LoginActivity.this, RegisterActivity.class);
startActivity(registerIntent);
}
Error line :
currentUserID = mAuth.getCurrentUser().getUid();
This is how I check if the user is logged in. If they are I send them to the MainActivity. If they are not they stay on the LoginActivity
if (UsersRef != null) {
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
You call
mAuth = FirebaseAuth.getInstance();
UsersRef = FirebaseDatabase.getInstance().getReference().child("Users");
and then
if (UsersRef != null) {
//do something
}
It's a bit odd because you need to know if there's currently a valid user logged in Firebase. This snippet maybe can be useful:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
// User is signed in
} else {
// No user is signed in
}
But you're checking if the variable UsersRef (that is a DatabaseReference, i guess) is null or not... Indeed you just gived it a value!!!
Use addOnSuccessListener instead of addOnCompleteListener
auth.signInWithEmailAndPassword(mEmail, mPassword)
.addOnSuccessListener(LoginActivity.this, new OnSuccessListener<AuthResult>(){
#Override
public void onsuccess(#NonNull AuthResult authResult){
//your code goes here
}
});
I enter my main activity, inside the MainActivity I have registration, after the registartion accure I want to log out from firebase so that he doesn't remember me.
Because when I retured to the MainActivity after the signout he still remembers the previous user when I register as a new user. This occurs only after logging and logout immediately. Btw, if I run the app its working fine. The problem is only when I signout and then going to RegistrationActivity to register another user.
Here is the MainActivity code:
public class MainActivity extends AppCompatActivity {
private SignInButton signIn;
private int RC_SIGN_IN=1;
private GoogleSignInClient mGoogleSignInClient;
private String TAG = "MainActivity";
private FirebaseAuth mAuth;
private Button registration;
private EditText email;
private EditText password;
private Button login;
private BottomNavigationView bottomNavigationItemView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
signIn = (SignInButton)findViewById(R.id.sign_in_button);
mAuth = FirebaseAuth.getInstance();
registration = (Button) findViewById(R.id.registrate);
email = (EditText)findViewById(R.id.email);
password = (EditText)findViewById(R.id.password);
login = (Button)findViewById(R.id.login);
bottomNavigationItemView = (BottomNavigationView)findViewById(R.id.navB) ;
bottomNavigationItemView.getMenu().getItem(0).setChecked(true);
bottomNavigationItemView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.register_menu: {
Intent intent = new Intent(MainActivity.this, RegistrationActivity.class);
startActivity(intent);
break;
}
}
return true;
}
});
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
signIn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
signIn();
}
});
registration.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, RegistrationActivity.class);
startActivity(intent);
}
});
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String email_text = email.getText().toString().trim();
String password_text = password.getText().toString().trim();
if(TextUtils.isEmpty(email_text) || TextUtils.isEmpty(password_text))
{
Toast.makeText(MainActivity.this, "One or more fields are empty", Toast.LENGTH_LONG).show();
}
else
{
mAuth.signInWithEmailAndPassword(email_text, password_text).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(!task.isSuccessful())
{
Toast.makeText(MainActivity.this, "Sign in problem", Toast.LENGTH_LONG).show();
}
else
{
Intent intent = new Intent(MainActivity.this, AccountActivity.class);
startActivity(intent);
}
}
});
}
}
});
}
private void signIn() { /*Sign in to the app with Google Account*/
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
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 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);
try{
GoogleSignInAccount account = task.getResult(ApiException.class);
firebaseAuthWithGoogle(account);
}
catch(ApiException e){
Log.w(TAG, "Google Sin in Failed");
}
}
}
private void firebaseAuthWithGoogle(GoogleSignInAccount acct)
{
Log.d(TAG, "firebaseAuthWithGoogle:" + acct.getId());
AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>()
{
#Override
public void onComplete(#NonNull Task<AuthResult> task)
{
if(task.isSuccessful())
{
Log.d(TAG, "signInWithCredential: success");
FirebaseUser user = mAuth.getCurrentUser();
updateUI(user);
}
else
{
Log.w(TAG, "signInWithCredential: failure", task.getException()); /*In case of unsuccessful login*/
Toast.makeText(MainActivity.this, "You are not able to log in to Google", Toast.LENGTH_LONG).show();
//updateUI(null);
}
}
});
}
private void updateUI(FirebaseUser user) /*In case of successful registration*/
{
GoogleSignInAccount acct = GoogleSignIn.getLastSignedInAccount(getApplicationContext());
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();
Toast.makeText(this, "Name of User : " + personName + "UserId is : " + personId, Toast.LENGTH_LONG);
Intent intent = new Intent(this, AccountActivity.class);
intent.putExtra("personPhoto", personPhoto.toString());
startActivity(intent);
}
}
Here is the AccountActivity code:
public class AccountActivity extends AppCompatActivity {
private GoogleSignInClient mGoogleSignInClient;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthStateListener;
private CardView signOut;
private CardView ratingTable;
private CardView settings;
private CardView map;
private CardView favoritePlaces;
DatabaseReference databaseReference;
FirebaseDatabase database;
List<User> users;
CollapsingToolbarLayout collapsingToolbarLayout;
String photoString="No photo";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_account);
mAuth = FirebaseAuth.getInstance();
signOut = (CardView) findViewById(R.id.logout);
ratingTable = (CardView) findViewById(R.id.rating);
settings = (CardView)findViewById(R.id.settings);
map = (CardView) findViewById(R.id.map);
favoritePlaces = (CardView)findViewById(R.id.favorite);
database = FirebaseDatabase.getInstance();
databaseReference = database.getReference();
users = new ArrayList<User>();
collapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collaps);
if(mAuth.getCurrentUser().getDisplayName()!=null)
{
Intent i = getIntent();
photoString = i.getStringExtra("personPhoto");
}
databaseReference.child("user").addValueEventListener(new ValueEventListener() { /*A new user is registered in the database*/
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Iterable<DataSnapshot> children = dataSnapshot.getChildren();
for (DataSnapshot child : children) {
User user = child.getValue(User.class);
users.add(user);
}
if (!findUser()) /*If the user is not found, this is a new user and must be registered*/
addUser();
showName(); /*A user-specific message*/
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
signOut.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mAuth.getCurrentUser().getDisplayName()!=null)
{
mGoogleSignInClient.signOut();
//Intent intent = new Intent(AccountActivity.this, MainActivity.class);
// startActivity(intent);
Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
else
{
mAuth.signOut();
Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
}
});
settings.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(AccountActivity.this, SettingsActivity.class);
startActivity(intent);
}
});
map.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(AccountActivity.this, MapsActivity.class);
startActivity(intent);
}
});
favoritePlaces.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(AccountActivity.this, favoritePlacesActivity.class);
startActivity(intent);
}
});
ratingTable.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(AccountActivity.this, RatingTableActivity.class);
startActivity(intent);
}
});
}
private void showName() /*A user-specific message*/
{
String name = "";
String userId = mAuth.getUid();
for (User tmpUser : users) {
if (userId.equals(tmpUser.getUserId()))
{
name = tmpUser.getUserName();
break;
}
}
collapsingToolbarLayout.setTitle("Hi " + name);
}
private boolean findUser() /*Check if a logged-on user is already registered in the database*/
{
FirebaseUser user = mAuth.getCurrentUser();
String userId = mAuth.getUid();
for (User tmpUser : users) {
if (userId.equals(tmpUser.getUserId())) {
return true;
}
}
return false;
}
private void addUser() /*In case of registration from Google Account*/
{
String userId = mAuth.getUid();
if(mAuth.getCurrentUser().getDisplayName()!=null) /*In case of registration not from Google Account*/
{
databaseReference = FirebaseDatabase.getInstance().getReference("user");
FirebaseUser user = mAuth.getCurrentUser();
String userName = user.getDisplayName();
User newUser = User.getInstance(userId, userName, photoString);
databaseReference.child(userId).setValue(newUser);
}
else /*If the user is not registered the function registers it in the database*/
{
databaseReference = FirebaseDatabase.getInstance().getReference("user");
Intent i = getIntent();
String firstName = i.getStringExtra("firstName");
String lastName = i.getStringExtra("lastName");
User newUser = User.getInstance(userId, firstName + " " + lastName, photoString);
databaseReference.child(userId).setValue(newUser);
}
}
RegistrationActivity code:
public class RegistrationActivity extends AppCompatActivity {
EditText email_text;
EditText pass1;
EditText pass2;
EditText first;
EditText last;
Button registrate;
FirebaseAuth mAuth;
private ProgressDialog progressDialog;
private BottomNavigationView bottomNavigationItemView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_registration);
mAuth = FirebaseAuth.getInstance();
progressDialog = new ProgressDialog(this);
email_text = (EditText)findViewById(R.id.email);
pass1 = (EditText)findViewById(R.id.password1);
pass2 = (EditText)findViewById(R.id.password2);
first = (EditText)findViewById(R.id.first_name);
last = (EditText)findViewById(R.id.last_name);
registrate = (Button)findViewById(R.id.registrate);
bottomNavigationItemView = (BottomNavigationView)findViewById(R.id.navB) ;
bottomNavigationItemView.getMenu().getItem(1).setChecked(true);
bottomNavigationItemView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.Signin_menu: {
Intent intent = new Intent(RegistrationActivity.this, MainActivity.class);
startActivity(intent);
break;
}
}
return true;
}
});
registrate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String email = email_text.getText().toString().trim();
String password1 = pass1.getText().toString().trim();
String password2 = pass2.getText().toString().trim();
final String first_name = first.getText().toString().trim();
final String last_name = last.getText().toString().trim();
boolean correctFlag=true;
/*All tests for input integrity*/
if(!password1.equals(password2))
{
Toast.makeText(RegistrationActivity.this, "The password does not match", Toast.LENGTH_LONG).show();
correctFlag=false;
}
if(password1.equals("") && password2.equals(""))
{
Toast.makeText(RegistrationActivity.this, "No password entered", Toast.LENGTH_LONG).show();
correctFlag=false;
}
if(email.equals("") || first_name.equals("") || last_name.equals(""))
{
Toast.makeText(RegistrationActivity.this, "One or more of the parameters are incorrect", Toast.LENGTH_LONG).show();
correctFlag=false;
}
if(correctFlag) /*There is no problem filling the fields*/
{
progressDialog.setMessage("Registrating user...");
progressDialog.show();
mAuth.createUserWithEmailAndPassword(email, password1).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful())
{
Toast.makeText(RegistrationActivity.this, "Registered Succesfully", Toast.LENGTH_SHORT).show();
progressDialog.cancel();
Intent intent = new Intent(RegistrationActivity.this, AccountActivity.class);
intent.putExtra("firstName", first_name);
intent.putExtra("lastName", last_name);
startActivity(intent);
}
else
{
Toast.makeText(RegistrationActivity.this, "could not register. please try again", Toast.LENGTH_SHORT).show();
progressDialog.cancel();
}
}
});
}
}
});
}
You need to log out of GoogleSignInClient :
public void signOut() {
signOutBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
GoogleSignInClient mGoogleSignInClient = GoogleSignIn.getClient(getContext(), gso);
mGoogleSignInClient.signOut();
FirebaseAuth.getInstance().signOut();
startActivity(new Intent(getContext(), LoginActivity.class));
}
});
}
My MainActivity contains a GoogleSignIn button which pops up a menu with all the google accounts on the device. All works fine. The user is able to log in successfully, and directed to a new Activity.
Now, the new Activity (Main2Activity) contains a log-out button, which redirects the user to MainActivity again. But when I click on GoogleSignIn button again, the same user is again logged in. I want the account selection menu to pop up once again. What if the user wants to signin with other account?
Here's the signout code I'm using in Main2Activity:
HomeActivity/Main2Activity
findViewById(R.id.logoutButton).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
firebaseAuth.signOut();
startActivity(new Intent(getApplicationContext(), LoginActivity.class));
finish();
}
});
}
LoginActivity/MainActivity
package com.dell.nfclib;
public class LoginActivity extends Activity
{
private static final int RC_SIGN_IN = 101;
GoogleSignInClient mGoogleSignInClient;
private FirebaseAuth mAuth;
SignInButton signInButton;
#Override
protected void onStart()
{
super.onStart();
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
// Configure Google Sign In
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
// Build a GoogleSignInClient with the options specified by gso.
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
// Initialize Firebase Auth
mAuth = FirebaseAuth.getInstance();
signInButton = (SignInButton) findViewById(R.id.googleSignInButton);
signInButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
signIn();
}
});
}
private void signIn()
{
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
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()) {
GoogleSignInAccount account = result.getSignInAccount();
firebaseAuthWithGoogle(account);
}
}
}
private void firebaseAuthWithGoogle(GoogleSignInAccount acct)
{
AuthCredential credential = GoogleAuthProvider.getCredential(acct.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
// Get user details from the 'user' object..
startActivity(new Intent(getApplicationContext(), HomeActivity.class));
finish();
}
else
{
// If sign in fails, display a message to the user.
Toast.makeText(getApplicationContext(), "Error", Toast.LENGTH_LONG).show();
}
// ...
}
});
}
}
But when I click on GoogleSignIn button again, the same user is again logged in.
This is happening because you haven't signed out completely.
I want the account selection menu to pop up once again.
To solve this, you need to sign-out from both, Firebase and Google accounts. A method like the following can help you solve your problem:
private void signOut() {
FirebaseFirestore.getInstance().signOut(); //Sign-out Firebase
if (googleApiClient.isConnected()) {
Auth.GoogleSignInApi.signOut(googleApiClient); //Sign-out Google
}
}