why I get wrong current user in firebase android xamarin - android

I use this code to define Current user and email in Firebase:
var CurrentUserEmail = FirebaseAuth.Instance.CurrentUser.Email;
It doesn't give the right user and email. Did you have the same issue?

I am not familiar with xamarin, but if you want to get a the current user or his/her email then you should make sure that the user is signed in or else you can't get these details, something like that:
//get the current user like that
var currentuser =FirebaseAuth.Instance.CurrentUser;
//check is user not null (in other words if user signed in)
if(currentuser != null){
//this means user is signed in
//get user uid
var uid= currentuser.Uid;
//get user email
var email= currnetuser.Email;
}

I found my mistake, in case who will meet the same case. I typed StartActivity right away after SignInWithEmailAndPassword:
auth.SignInWithEmailAndPassword(email,password)
.AddOnCompleteListener(this,this);
StartActivity(intent); // incorrect
Right way to do it :
auth.SignInWithEmailAndPassword(email,password)
.AddOnCompleteListener(this,this);
...
public void OnComplete(Task task)
{
if(task.IsSuccessful){
StartActivity(intent);
Finish();
}
}

first you must declare private FirebaseAuth _auth; as a property of your activity.
Then you can access your currentUser this way :
FirebaseUser currentUser = _auth.CurrentUser;

Related

Logout function not clearing ParseUser currentUser after parse migration in Android

I am using Parse SDK 1.13.1 for Android and I need to logout user on button click. it's working but when I call ParseUser.getCurrentUser() it's give me last logged in user instead of null.
For Parse Initialize i write below code :
Parse.initialize(new Parse.Configuration.Builder(this).applicationId("PARSE_APPLICATIONID").clientKey("PARSE_CLIENT_KEY").server("PARSE_SERVER_URL").build());
For logout i write below code
ParseUser.logOut();
and also tried
ParseUser.getCurrentUser().logOut();
ParseUser currentUser = ParseUser.getCurrentUser(); // this should be null but not
But, it seems that ParseUser.getCurrentUser(); after log out is not null.
How I can remove current user from cache?
Please help me to resolve this. Thanks
Whenever you use any signup or login methods, the user is cached on disk. You can treat this cache as a session, and automatically assume the user is logged in.
ParseUser currentUser = ParseUser.getCurrentUser();
if (currentUser != null) {
// do stuff with the user
} else {
// show the signup or login screen
}
You can clear the current user by logging them out.
ParseUser.logOut();
ParseUser currentUser = ParseUser.getCurrentUser(); // this will now be null
Make sure that you have all your functions correctly set and that you not authenticating the user again etc.
If you have Automatic user creation enabled, logging out and then fetching the current user will produce a new anonymous user. This on by default in the starter projects so that you can start using users and ACLs immediately.
if [PFUser enableAutomaticUser]; set in your appDelegate, current user will never return nill
Please check below:
public static Task<Void> logOutInBackground()
or
public static void logOutInBackground(LogOutCallback callback)
method with ParseUser Like below:
ParseUser.logOutInBackground(); or
ParseUser.logOutInBackground(new LogOutCallback )
Hope it will work...

Firebase isEmailVerified returns false even after verifying email

I send email verification and click the link. Then I call isEmailVerified() on FirebaseUser object. This always return null, what may be the reason?
You should refresh the user object after verification as follows :
usertask = mAuth.getCurrentUser().reload();
usertask.addOnSuccessListener(new OnSuccessListener() {
#override
public void onSuccess(Void aVoid) {
user = mAuth.getCurrentUser();
boolean useremailveri = user.isEmailVerified();
String useremailuid = user.getUid();
}
});
First you have to call this method : signInWithEmailAndPassword , at least 1 time after user has verified their email ....
Only after that, you will get isEmailVerified() as true
Change isEmailVerified() to emailVerified;
Re-authenticates the user who updates if the email has been verified ...
https://firebase.google.com/docs/auth/android/manage-users#re-authenticate_a_user
Same technique as #yehyatt´s solution but easier. Sign the user in with firebase, refresh the user and then check if the user is verified.
Sign the user In
Auth.auth().signIn(withEmail: YourEMail, password: YourPassword) { result, error in
if error != nil {
logInErrorReason = "\(error!.localizedDescription)"
// An error ocurred
}else {
// Handle successful login.
}
}
Refresh current user:
Auth.auth().currentUser?.reload(completion: ((Error?) -> Void)?)
Check if he is signed in:
if Auth.auth().currentUser?.isEmailVerified == true { // Handle successful verification}
I think you need to first login with user's Email and Password using signInWithEmailAndPassword then try calling isEmailVerified()
method on returning user.
isEmailVerified should provide correct response, however you might be using it incorrectly.
If user verified his email ( he/she received an email from firebase, and clicked on "verify email" link ) then it will return true;
If user didn't verified his email - it will return false
So solution for this issue is to update you registration process.
When you create new user you should also issue a command to start email verification process await user.sendEmailVerification();
once your user will receive an email and will verify it. your method : user.isEmailVerified will return true
Your registration process should look something like that:
AuthResult result = await _auth.createUserWithEmailAndPassword(
email: email,password: password);
FirebaseUser user = result.user;
await user.sendEmailVerification();
Create new user using createUserWithEmailAndPassword
Let it send verification link to your gmail using sendEmailVerification
go to your own gmail, you will see verification link and just click
on that link
try to login with username and email
You will see your own account had already verified and can proceed next setps
https://github.com/FirebaseExtended/flutterfire/issues/2208

Change password with Firebase for Android

I want to implement change password functionality for my application.
I included com.google.firebase:firebase-auth:9.0.2 in my build.gradle file and so far everything has been working fine until I tried to implement change password functionality.
I found that the FirebaseUser object has a updatePassword method that takes a new password as the parameter. I could use this method and implement validation myself. However, I need the user's current password for comparing with the inputted one and I can't find a way to get that password.
I also found another method on the Firebase object that takes the old password, new password, and a handler. The problem is that I need to also include com.firebase:firebase-client-android:2.5.2+ to access this class and when I am trying this method I'm getting to following error:
Projects created at console.firebase.google.com must use the new Firebase Authentication SDKs available from firebase.google.com/docs/auth/
Feel like I'm missing something here. What's the recommended approach for implementing this? And when to use what dependency?
I found a handy example of this in the Firebase docs:
Some security-sensitive actions—such as deleting an account, setting a
primary email address, and changing a password—require that the user
has recently signed in. If you perform one of these actions, and the
user signed in too long ago, the action fails and throws
FirebaseAuthRecentLoginRequiredException. When this happens,
re-authenticate the user by getting new sign-in credentials from the
user and passing the credentials to reauthenticate. For example:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
// Get auth credentials from the user for re-authentication. The example below shows
// email and password credentials but there are multiple possible providers,
// such as GoogleAuthProvider or FacebookAuthProvider.
AuthCredential credential = EmailAuthProvider
.getCredential("user#example.com", "password1234");
// Prompt the user to re-provide their sign-in credentials
user.reauthenticate(credential)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
user.updatePassword(newPass).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "Password updated");
} else {
Log.d(TAG, "Error password not updated")
}
}
});
} else {
Log.d(TAG, "Error auth failed")
}
}
});
Changing password in firebase is bit tricky. it's not like what we usually do for changing password in server side scripting and database. to implement change password functionality in your app, first you need to get the user's email from FirebaseAuth or prompt user to input email and after that prompt the user to input old password because you can't retrieve user's password as Frank van Puffelen said. After that you need to reauthenticate that. Once reauthentication is done, if successful, you can use updatePassword(). I have added a sample below that i used for my own app. Hope, it will help you.
private FirebaseUser user;
user = FirebaseAuth.getInstance().getCurrentUser();
final String email = user.getEmail();
AuthCredential credential = EmailAuthProvider.getCredential(email,oldpass);
user.reauthenticate(credential).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
user.updatePassword(newPass).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(!task.isSuccessful()){
Snackbar snackbar_fail = Snackbar
.make(coordinatorLayout, "Something went wrong. Please try again later", Snackbar.LENGTH_LONG);
snackbar_fail.show();
}else {
Snackbar snackbar_su = Snackbar
.make(coordinatorLayout, "Password Successfully Modified", Snackbar.LENGTH_LONG);
snackbar_su.show();
}
}
});
}else {
Snackbar snackbar_su = Snackbar
.make(coordinatorLayout, "Authentication Failed", Snackbar.LENGTH_LONG);
snackbar_su.show();
}
}
});
}
}
There is no way to retrieve the current password of a user from Firebase Authentication.
One way to allow your users to change their password is to show a dialog where they enter their current password and the new password they'd like. You then sign in (or re-authenticate) the user with the current passwordand call updatePassword() to update it.
I googled something about resetting Firebase passwords and got to this page. It was helpful but didn't get me all the way to the finish line: I still had to Google around for five or ten minutes. So I'm back to improve the answer for VueJS users.
I see lots of code here using "FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();" in the top line. That's a piece of the puzzle mentioned in the most popular two answers.
But I couldn't get that to work in my project, which is written in VueJS. So I had to go exploring.
What I found was another page of the Firebase documentation. It's the same page people are getting the quoted code from (I think), but with the documentation written for Web instead of Android/Java.
So check out the first link if you're here using VueJS. I think it'll be helpful. "Get the currently signed-in user" might contain the appropriate code for your project. The code I found there says:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
});
That page I linked up above ("another page") brought me eventually to the "Set a user's password" part of the Web docs. Posters here correctly state that the user must have been authenticated recently to initiate a password update. Try this link for more on re-authenticating users.
"Set a user's password":
// You can set a user's password with the updatePassword method. For example:
var user = firebase.auth().currentUser;
var newPassword = getASecureRandomPassword();
user.updatePassword(newPassword).then(function() {
// Update successful.
}).catch(function(error) {
// An error happened.
});
"Re-authenticate a user"
var user = firebase.auth().currentUser;
var credential;
// Prompt the user to re-provide their sign-in credentials
user.reauthenticateWithCredential(credential).then(function() {
// User re-authenticated.
}).catch(function(error) {
// An error happened.
});
Query revolves around users forgetting their passwords or wishing to reset their passwords via an email letter. Which can be attained by Auth.sendPasswordResetEmail("email#gmail.com");
begin by initializing
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private String DummyEmail = "Dummy#gmail.com"
mAuth = FirebaseAuth.getInstance();
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
if (firebaseAuth.getCurrentUser() == null) {
}
}
};
Somewhere else when a user requests to update or reset their passwords simply access the mAuth,
private void PassResetViaEmail(){
if(mAuth != null) {
Log.w(" if Email authenticated", "Recovery Email has been sent to " + DummyEmail);
mAuth.sendPasswordResetEmail(DummyEmail);
} else {
Log.w(" error ", " bad entry ");
}
}
Now, needless to burden yourself querying around your database to find whether the Email exits or not, Firebase mAuth will handle that for you.
Is the Email authenticated? Is it active in your Authentication list? Then send a password-reset Email.
The content will look something like this
the reset link will prompt the following dialog on a new web page
Extra
if you're bit nerved by the reset-template "devised" by Firebase. You can easily access and customize your own letter from the Firebase Console.
Authentication > Email templates > Password reset
A simple approach to handle changing a password is to send a password reset email to the user.
FirebaseAuth.getInstance().sendPasswordResetEmail("user#example.org")
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(Activity.this, "Password Reset Email Sent!"), Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(Activity.this, task.getException().getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
});
This is a kotlin solution to the problem I am putting the method here Hope it helps
// The method takes current users email (currentUserEmail), current users old password (oldUserPassword), new users password (newUserPassword) as parameter and change the user password to newUserPassword
private fun fireBasePasswordChange(
currentUserEmail: String,
oldUserPassword: String,
newUserPassword: String
) {
// To re authenticate the user credentials getting current sign in credentials
val credential: AuthCredential =
EmailAuthProvider.getCredential(currentUserEmail, oldUserPassword)
// creating current users instance
val user: FirebaseUser? = FirebaseAuth.getInstance().currentUser
// creating after successfully re authenticating update password will be called else it will provide a toast about the error ( makeToast is a user defined function here for providing a toast to the user)
user?.reauthenticate(credential)?.addOnCompleteListener { task ->
when {
task.isSuccessful -> {
user.updatePassword(newUserPassword).addOnCompleteListener {
if (it.isSuccessful) {
makeToast("Password updated")
// This part is optional
// it is signing out the user from the current status once changing password is successful
// it is changing the activity and going to the sign in page while clearing the backstack so the user cant come to the current state by back pressing
FirebaseAuth.getInstance().signOut()
val i = Intent(activity, SignInActivity::class.java)
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(i)
(activity as Activity?)!!.overridePendingTransition(0, 0)
} else
makeToast("Error password not updated")
}
}
else -> {
makeToast("Incorrect old password")
}
}
}
}

firebaseAuth.getCurrentUser() return null DisplayName

When I signIn with my google account and get the name with the getDisplayName(), my name appear correctly, but in the AuthStateListener doesn't.
here part of my code:
private void handleSignInResult(GoogleSignInResult result) {
Alert.dismissProgress();
if (result.isSuccess()) {
GoogleSignInAccount acct = result.getSignInAccount();
if(acct != null) {
Log.i("NAME", acct.getDisplayName()); <-- RETURN MY NAME CORRECTLY
credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
fuser.linkWithCredential(credential).addOnCompleteListener(authResult);
} else {
//ERROR
}
} else {
//ERROR
}
}
But in my AuthStateListener
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser nuser = firebaseAuth.getCurrentUser();
if (nuser != null) {
Log.i("NAME", nuser.getDisplayName()); <--- RETURN NULL
}
}
Somebody know why this can happen?
This is a tricky one since it is not so clear in the documentation...
Check the getProviderData()
as defined here:
https://firebase.google.com/docs/reference/android/com/google/firebase/auth/FirebaseUser#public-method-summary
You can iterate that List and it will have all the providers associated with that account, included a provider with the providerId = "google.com" with a display Name = YOUR_GOOGLE_USERNAME
let me know if you cannot make it work
Just to add to Ymmanuel's answer (Thank you!) with some example code for anyone else looking for a quick copy and paste:
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
// User is signed in
String displayName = user.getDisplayName();
Uri profileUri = user.getPhotoUrl();
// If the above were null, iterate the provider data
// and set with the first non null data
for (UserInfo userInfo : user.getProviderData()) {
if (displayName == null && userInfo.getDisplayName() != null) {
displayName = userInfo.getDisplayName();
}
if (profileUri == null && userInfo.getPhotoUrl() != null) {
profileUri = userInfo.getPhotoUrl();
}
}
accountNameTextView.setText(displayName);
emailTextView.setText(user.getEmail());
if (profileUri != null) {
Glide.with(this)
.load(profileUri)
.fitCenter()
.into(userProfilePicture);
}
}
The above will try to use the first display name and photo url from the providers if it wasn't initially found in the User object.
Bonus: Using glide for images: https://github.com/bumptech/glide .
Edmund Johnson is right. This issue was introduced in Firebase Auth 9.8.0. A workaround includes downgrading to 9.6.1 or forcing 're-login' as the info is populated after the user logs out and logs back in. The problem is described in the Firebase issue
It has been reported as a bug to Firebase by one of the Firebase UI contributors - Alex Saveau.
I had the same issue, I solved it by signing out the user and resigning them back in.
Call FirebaseAuth.getInstance().signOut(); to sign them out, then try again.
As I've discovered, this issue is common with using email/password authentication and Social login (Facebook in my case) at the same time.
I found a solution for this problem, in the Firebase documentation!
The solution is to update the user profile using the: UserProfileChangeRequest:
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(mUser.getName())
.setPhotoUri(Uri.parse("https://example.com/mario-h-user/profile.jpg"))
.build();
firebaseUser.updateProfile(profileUpdates)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "User profile updated.");
}
}
});
The variable mUser is already filled with the content from the fields.
I used this piece of code inside the FirebaseAuth.AuthStateListener() -> onAuthStateChanged()
This issue is resolved in the latest verison of firebase ui
compile 'com.firebaseui:firebase-ui:1.2.0'
First let me say there's no need to downgrade the Gradle files or logout and login the user multiple times as stated by others just to display the user name. I've solved the issue a different way while still keeping the latest Gradle files and not having to log the user out and in multiple times. The issue with getDisplayName() is a very big one so I want to be as descriptive as possible for future users of Firebase to spare them the headache.
Here are the details of the solution:
Solution 1:
For users who authenticate(sign-in) with multiple providers such as Facebook, Google etc. and/or Email/Password that they created at sign-up:
The first thing you want to ensure is that when you have a user sign-up with the app for the first time you store their name of course to the database under their unique id. Which may look something like this:
// Method signature. Write current user's data to database
private void writeNewUser(String userId, String name, String email) {
DatabaseReference current_user_database = mDatabaseRef.child(userId);
current_user_database.child("username").setValue(name);
// Email here is not mandatory for the solution. Just here for clarity of the
// method signature
current_user_database.child("email").setValue(email);
}
After the user's name has been stored in your Firebase database and you have them sign into your app you can get their username something like this:
// Method that displays the user's username
private void showUserName() {
// Get instance of the current user signed-in
mFirebaseUser = mAuth.getCurrentUser();
// Check if user using sign-in provider account is currently signed in
if (mFirebaseUser != null) {
// Get the profile information retrieved from the sign-in provider(s) linked to a user
for (UserInfo profile : mFirebaseUser.getProviderData()) {
// Name of the provider service the user signed in with (Facebook, Google, Twitter, Firebase, etc.)
String name = profile.getDisplayName();
// If displayName() is null this means that the user signed in using the email and password they created. This is the null issue we shouldn't get that we are gonna be solving below.
if(name == null){
mDatabaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get the name the user signed-up with using dataSnapshot
String nameOfCurrentUser = (String) dataSnapshot.child("name").getValue();
// Set username we retrieved using dataSnapshot to the view
mTestUsernameTextView.setTitle(nameOfCurrentUser);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
// If the name is not null that means the user signed in with a social Auth provider such as Facebook, Twitter, Google etc.
if(name != null) {
// Set the TextView (or whatever view you use) to the user's name.
mTestUsernameTextView.setText(name);
}
} // End for
} // End if
}
That's it. Now you just call that method showUserName() or whatever your method is gonna be called inside your onCreate and hopefully this helps.
Solution 2:
For users who sign into your app using ONLY a social media service provider such as Facebook, Twitter, Google or whatever other option Firebase allows:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
for (UserInfo profile : user.getProviderData()) {
// Id of the provider (ex: google.com)
String providerId = profile.getProviderId();
// UID specific to the provider
String uid = profile.getUid();
// Name, email address, and profile photo Url
String name = profile.getDisplayName();
String email = profile.getEmail();
Uri photoUrl = profile.getPhotoUrl();
};
}
That's it for solution 2, just follow the guidelines on Firebase for that and you should be good.
Here's a link to it if you're curious:
Get a user's profile information
I truly hope this helps anyone struggling with the getDisplayName() issue.
Conclusion:
If your app only has Facebook, Twitter, Google or whatever else social media sign-in options Firebase provides then just simply calling getDisplayName()method on the currently signed in user should be enough to show their username.
Otherwise if your app allows the user to sign in using an email/password they created then make sure you got their name/username at sign-up so that you can use it later on to display it.
I was getting this problem when I had:
implementation 'com.google.firebase:firebase-auth:10.0.0'
implementation 'com.firebaseui:firebase-ui-auth:1.0.1'
A workaround that fixed it for me was to replace that with:
implementation 'com.google.firebase:firebase-auth:9.6.0'
implementation 'com.firebaseui:firebase-ui-auth:0.6.0'
Iterating through user.getProviderData() as suggested elsewhere didn't fix it for the later versions.
Based on Alan's and Ymmanuel's answers here's the 2 helper methods that I'm using:
public static String getDisplayName(FirebaseUser user) {
String displayName = user.getDisplayName();
if (!TextUtils.isEmpty(displayName)) {
return displayName;
}
for (UserInfo userInfo : user.getProviderData()) {
if (!TextUtils.isEmpty(userInfo.getDisplayName())) {
return userInfo.getDisplayName();
}
}
return null;
}
public static Uri getPhotoUrl(FirebaseUser user) {
Uri photoUrl = user.getPhotoUrl();
if (photoUrl != null) {
return photoUrl;
}
for (UserInfo userInfo : user.getProviderData()) {
if (userInfo.getPhotoUrl() != null) {
return userInfo.getPhotoUrl();
}
}
return null;
}

Parse User log out does not work

I am using Parse 1.9.0 for Android and I need to log out user on button click, so I call:
ParseUser.logOut();
After that I need to open login screen and click on Facebook login button, and to check if user have saved custom custom field.
But, it seems that ParseUser.getCurrentUser() after log out is not null.
How I can remove current user from cache?
Try this:
ParseUser.logOut();
ParseUser currentUser = ParseUser.getCurrentUser(); // this will now be null
The logout() method is called from the current user object itself and to obtain it you call ParseUser.getCurrentUser() and then logout like below:
ParseUser.getCurrentUser().logOut();
now the current user is null.
if ParseUser.enableAutomaticUser(); isn't called anywhere the current user will only be logged in using :
ParseUser.logInInBackground(username, password);
ParseUser parseUser = /*your user data here*/;
parseUser.signUpInBackground();
Don't know what you want to do! But you can check at the onCreate method if the Current User is an Anonymous user and thus prevent it to auto-load Anonymous userData from the cache:
if (ParseAnonymousUtils.isLinked(ParseUser.getCurrentUser())) {
//This is a Logged out Anonymous user
} else {
//Getting Current User who is not logged off
ParseUser currentUser = ParseUser.getCurrentUser();
if (currentUser != null) {
//Do your staff
}
}

Categories

Resources