I am creating authentication with facebook for my application and everything is working fine except that when I am signed out of facebook it still passes me to the main menu of the application. Which I assume means that .getCurrentUser() does not return null even if I am signed out.
I've tried commenting out updateUI(); in my code below and that seems to fix the problem, however I would like for this code to work properly
FirebaseUser currentUser = mAuth.getCurrentUser();
if(currentUser != null) {
updateUI();
}
You need to attach an authstate listener.
"There are some cases where getCurrentUser will return a non-null FirebaseUser but the underlying token is not valid. This can happen, for example, if the user was deleted on another device and the local token has not refreshed. In this case, you may get a valid user getCurrentUser but subsequent calls to authenticated resources will fail.
getCurrentUser might also return null because the auth object has not finished initializing.
If you attach an AuthStateListener you will get a callback every time the underlying token state changes. This can be useful to react to edge cases like those mentioned above."
https://firebase.google.com/docs/reference/android/com/google/firebase/auth/FirebaseAuth.AuthStateListener
https://firebase.google.com/docs/auth/android/manage-users
Try using AuthStateListener, sample:
//Declaration and defination
private FirebaseAuth firebaseAuth;
FirebaseAuth.AuthStateListener authStateListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
if (firebaseAuth.getCurrentUser() != null){
//Do anything here which needs to be done after user is set is complete
updateUI();
}
else {
}
}
};
//Init and attach
firebaseAuth = FirebaseAuth.getInstance();
firebaseAuth.addAuthStateListener(authStateListener);
Related
Register Button in Register Acvtivity
public void registerBtnClicked(View view){
String email = binding.userEmailEditText.getText().toString();
String password = binding.userPasswordEditText.getText().toString();
String userNameData = binding.usernameEditText.getText().toString();
user = new Users(userNameData,email,password);
db = FirebaseDatabase.getInstance();
databaseReference = db.getReference(Users.class.getSimpleName());
databaseReference.push().setValue(user);
if(email.equals("") || password.equals("")){
Toast.makeText(this, "Enter email and password", Toast.LENGTH_LONG).show();
}else{
auth.createUserWithEmailAndPassword(email,password).addOnSuccessListener(new OnSuccessListener<AuthResult>() {
#Override
public void onSuccess(AuthResult authResult) {
Intent intent = new Intent(RegisterPage.this, MainActivity.class);
startActivity(intent);
finish();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(RegisterPage.this, e.getLocalizedMessage(),Toast.LENGTH_LONG).show();
}
});
}
}
I created a real time database.But I couldn't figure out how to show username in navigation header section. Can you help me?
If I understand correctly, the firebaseUser is null when you're trying to read the display name from it. This is actually a common scenario, as the user's sign-in session is managed by Firebase in the background, and the current user may change at any time.
The simple fix is to check whether there is a current user before accessing their display name, which you can do with:
firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
if (firebaseUser != null) {
navUserEmail.setText(firebaseUser.getEmail());
navUserName.setText(firebaseUser.getDisplayName());
}
Note though that the display name is an optional property of the user profile, so it can indeed be null. If you want to display nothing in that case, you can do:
String displayName = firebaseUser.getDisplayName();
navUserName.setText(displayName != null ? displayName : "");
Even if you've set the display name of a user, it may take up to an hour until that is updated for all connected clients, as they all cache the user profile. And since such updates happen in the background... 👇
To correctly handle all auth state changes, you'll want to use an auth state listener, as shown in this article: https://stackoverflow.com/collectives/google-cloud/articles/68104924/listen-for-authentication-state-in-android
From the title, you would think that there is a published solution to my problem, but in fact I believe I read everything pertinent to my question, but nothing quite matched up. Here's what I've got:
First of all, this problem has never happened in my app before today, nor did my sign-in change in any way: same Google sign-in code, same account. Everything the same for the past three months, as long as I've been testing. And, as far as I can tell, the problem only occurs with a single account. When the user begins the sign-in process, they are presented with a choice of accounts to sign in with; in this case, I selected the first user:
Next, Google authenticates the user and we arrive here in the code:
So the question is, why did Firebase suddenly stop providing the display name (and the photo URL)? From the first screenshot, it's clear that the user has a specified name and photo. Apart from that, FirebaseAuth.getInstance().getCurrentUser().isAnonymous() is false, as expected. Any ideas on why this suddenly broke would be greatly appreciated!
I solved the problem by simply updating my name and photo URL using UserProfileChangeRequest() and the name and photo URL of my Google account, as suggested here:
private void firebaseAuthWithGoogle(GoogleSignInAccount acct) {
sendFirebaseEvent(FIREBASE_GOOGLE_AUTH_EVENT, FIREBASE_GOOGLE_AUTH_KEY, acct.getId());
// [START_EXCLUDE silent]
showProgressDialog();
googleAccount = acct;
// [END_EXCLUDE]
final 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
sendFirebaseEvent(FIREBASE_GOOGLE_AUTH_EVENT, FIREBASE_GOOGLE_AUTH_RESULT_KEY, "Success");
launchNextActivity();
} else {
// If sign in fails, display a message to the user.
sendFirebaseEvent(FIREBASE_GOOGLE_AUTH_EVENT, FIREBASE_GOOGLE_AUTH_RESULT_KEY, task.getException().getMessage());
Snackbar.make(findViewById(R.id.main_layout), "Authentication Failed.", Snackbar.LENGTH_SHORT).show();
updateUI(null);
}
// [START_EXCLUDE]
hideProgressDialog();
// [END_EXCLUDE]
}
});
}
private void launchNextActivity() {
mFirebaseAuth = FirebaseAuth.getInstance();
FirebaseUser mUser = mFirebaseAuth.getCurrentUser();
if (mUser.getDisplayName() == null || mUser.getDisplayName().length() == 0) {
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(googleAccount.getDisplayName())
.setPhotoUri(googleAccount.getPhotoUrl())
.build();
mUser.updateProfile(profileUpdates);
}
}
I'm using Firebase Auth with Google and doing everyrhing through Firebase docs, and in my SigninActivity, I have onStart method, which check is there are current user or no.
#Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart");
// Check if user is signed in (non-null) and update UI accordingly.
FirebaseUser currentUser = mAuth.getCurrentUser();
updateUI(currentUser);
}
and also have
FirebaseAuth.getInstance().signOut();
which signs out user.
And i cannot understand, how Firebase defines current user, when he not logged in yet.
Is there are unique ID for app or how ?
According to your comments:
Yes, And also i dont understand, how Firebase knows current user, when he not signed in yet ? I mean, which criteria Firebase checks in this method FirebaseUser currentUser = mAuth.getCurrentUser()
Firebase "knows" when the current user is logged in or not by checking the FirebaseUser object for nullity. If the user is logged in, when using the following line of code:
FirebaseUser currentUser = mAuth.getCurrentUser();
It returns a non nullable FirebaseUser object. This is the reason why we always check it for nullity. If you are using the following line of code:
FirebaseAuth.getInstance().signOut();
It means that the FirebaseUser becomes null, which also means that the user has signed out.
I wanted to fetch the user details like name, email id and image when a user logs in with google on the navigation drawer header. I successfully authenticated the user via Google sign in but the app crashes while setting name email and picture on the drawer.
The error shows:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.replace(java.lang.CharSequence, java.lang.CharSequence)' on a null object reference
And the code related to it is
FirebaseDatabase.getInstance().getReference(Constants.USER_KEY).child(mFirebaseUser.getEmail().replace(".", ","))
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue() != null){
Users users = dataSnapshot.getValue(Users.class);
Glide.with(MainActivity.this)
.load(users.getPhotoUrl())
.into(mDisplayImageView);
mNameTextView.setText(users.getUser());
mEmailTextView.setText(users.getEmail());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Is there any way to fix this issue? Or an alternative way?
Your error message tells you the exact problem in your code. So you are calling replace() method on a null object reference. Which means that mFirebaseUser.getEmail() return null. To solve this, you need to instantiate the mFirebaseUser object before actually using it, like this:
FirebaseUser mFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
And to get user email, just use the following line of code:
if (mFirebaseUser == null) {
String userEmail = mFirebaseUser.getEmail();
}
I'm having a problem pulling images from Firebase Storage. I get the error message:
com.google.firebase.storage.StorageException: User does not have permission to access this object.
I have changed the permissions in firebase to all of the following and none of them work.
1.
service firebase.storage {
match /b/wics-application.appspot.com/o {
match /public/{allPaths=**} {
allow read, write: if request.auth == null;
}
match /user/{allPaths=**} {
allow read, write: if request.auth == null;
}
match /auth/{allPaths=**} {
allow read, write: if request.auth == null;
}
}
}
2.
service firebase.storage {
match /b/wics-application.appspot.com/o {
match /{allPaths=**} {
allow read, write;
}
}
}
Is there any other reason that I could be getting this message?
Have you created an instance of FirebaseUser?
FirebaseAuth mAuth;
FirebaseUser mUser;
Above onCreate and in onCreate
mAuth = FirebaseAuth.getInstance();
mUser = mAuth.getCurrentUser();
Then call your storage