I am pretty new to android development and Firebase(the new google one). I want to use the email and password feature, but sign specific users in(the ones in my firebase console). I know this is a pretty broad question, but any help would be much appreciated.
First of all, you should check a documentation for Firebase. You can find on official Firebase website:
1. https://firebase.google.com/docs/auth/android/manage-users
2. https://firebase.google.com/docs/auth/android/password-auth
Then you should check Firebase Authentication samples and look for Email/Password Setup.
After you have created your project and added your app to it, you have to go to the console/auth/sign_in method and enable the email and password authentication. Then you have to create a activity/fragment to represent the login, sign up etc.
On the launcher activity you should have this method to check the state of current user and do the necessary action of user != null or if user == null based on your preferences.
FirebaseAuth.AuthStateListener authStateListener;
authStateListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null){
startActivity(new Intent(LoginPage.this,MainActivity.class));
}
}
};
auth.addAuthStateListener(authStateListener);//this one in onStart
then you can use these 2 methods for signin and create new user respectively
FirebaseAuth auth;
auth = FirebaseAuth.getInstance();
auth.signInWithEmailAndPassword(email , password)
.addOnCompleteListener(LoginPage.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()){
}else {
}
}
});
auth.createUserWithEmailAndPassword(email,password)
.addOnCompleteListener(SignUpPage.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()){
}else {
}
}
});
go to all the links provided by mmBs and also see this link for a simple and working example
Related
I'm using Firebase Authentication in my app (email and password auth).
In the onStart() method of my Login activity I retrieve the current user using:
FirebaseUser currentUser = mAuth.getCurrentUser();
The problem comes when the user is deleted from the database, the mAuth.getCurrentUser() method still retrieves the user and allows authentication.
How can I check if the user still exists?
Thx!
Try using something like this:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref.child("users").child("email").addListenerForSingleValueEvent(new
ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
// used "email" already exists and is not deleted
} else {
// User does not exist. Add here your logic if the user doesn't exist
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Or check some of the following SO questions and answers:
Firebase authentication for checking if the user exists in the database or not
Firebase Auth - with Email and Password - Check user already registered
You can use getInstance. This worked for me fine. You don't get an instance with it.
private boolean isSignedIn() {
return FirebaseAuth.getInstance().getCurrentUser() != null;
}
Delete the userdata and make the currentuser null:
Follow the below code.
final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
user.delete()
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "User account deleted.");
//Remove the information f the user from database.
}
}
});
The code below works great on android to confirm if the Firebase Auth user still exists (has not been deleted or disabled) and has valid credentials.
Deleting the Auth user from the firebase console does not revoke auth tokens on devices the user is currently logged in as the token is cached locally. Using reload() forces a check with the firebase auth server.
currentUser.reload().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
//User still exists and credentials are valid
}else {
//User has been disabled, deleted or login credentials are no longer valid,
//so send them to Login screen
}
}
});
I am trying to sign in with facebook in the reinstallation of an android app. Initially I signed up using Google and successfully linked it with firebase.
But when I try to do with facebook it gives a
FirebaseAuthUserCollisionException
I read in the Firebase Documentation that you can do so by
FirebaseUser prevUser = currentUser;
currentUser = auth.signInWithCredential(credential).await().getUser();
// Merge prevUser and currentUser accounts and data
// ...
but here await() method no longer exists. Also after searching a bit I found out this solution
Tasks.await(mAuth.signInWithCredential(credential)).getUser();
But this also gives an error when getting the current user which is already linked. What can I do to solve this?
There is no need in .await() method to get firebase user.
Use FirebaseAuth.AuthStateListenerinstead.
So you implement firebase sign in with something like this:
FirebaseAuth.getInstance()signInWithCredential(credential)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Log.d(TAG, "login success");
} else {
Log.d(TAG, "login error");
}
}
});
And implement AuthStateListener which is trigerred every time user state is changed:
private FirebaseAuth.AuthStateListener authStateListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initAuthStateListener();
}
private void initAuthStateListener() {
authStateListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user == null) {
//user is not logged in
} else {
//user is logged in
//logic to finish the activity and proceed to the app can be put here
}
}
};
}
#Override
protected void onStart() {
super.onStart();
FirebaseAuth.getInstance().addAuthStateListener(authStateListener);
}
#Override
protected void onStop() {
super.onStop();
FirebaseAuth.getInstance().removeAuthStateListener(authStateListener);
}
Note: onAuthStateChanged is trigerred once when authStateListener is added to firebase auth instance.
Also make sure Prevent creation of multiple accounts with the same email address parameter is set on firebase console (Authentication >> SIGN-IN METHOD >> Advanced >> One account per email address (Change) ).
I referenced the documentation in Firebase page. My problem is in this paragraph:
The call to linkWithCredential will fail if the credentials are already linked to another user account. In this situation, you must handle merging the accounts and associated data as appropriate for your app:
FirebaseUser prevUser = currentUser; currentUser = auth.signInWithCredential(credential).await().getUser(); // Merge
prevUser and currentUser accounts and data // ...
I can't figure out how to add this code into my project. When and where do I put this code
auth.signInWithCredential(credential).await().getUser();
into my java file? Android Studio announced me that it can't resolve await() method.
What should I do to resolve that problem. Thank you in advance!
You should handle this part of code when the linkWithCredentials call fails.
Here is a small example :
mAuth.getCurrentUser().linkWithCredential(credentials).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (!task.isSuccessful()) {
FirebaseUser prevUser = currentUser;
try {
currentUser = Tasks.await(auth.signInWithCredential(credential)).getUser();
} catch (Exception e) {
e.printStackStrace();
}
// Merge prevUser and currentUser accounts and data
// ...
} else {
}
}
});
NB: Task.await() doesn't exist anymore you should use Tasks.await(...) static method instead.
Suppose that:
One account per email address setting is enabled on firebase authentication
User are logging in with anonymous authentication
The linkWithCredential usually fails with FirebaseAuthUserCollisionException, it could happen either because this credential is used to login before (you can check by searching this email on firebase console) or this email account is used to login before but with different providers ( such as a user logged in with abc#gmail.com by using google sign in before, now he/she uses abc#gmail.com but with Facebook login ) To handle it, you need 2 steps:
Step 1: link with anonymous account
private void linkWithAnonymousAccount(final AuthCredential credential) {
mFirebaseAuth.getCurrentUser().linkWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
getFirebaseToken();
} else {
Exception exception = task.getException();
if (exception instanceof FirebaseAuthUserCollisionException) {
signInWithFirebase(credential);
} else {
Utils.showDialogMessage(mContext, task.getException().getLocalizedMessage());
}
}
}
});
}
Step 2: sign with firebase
private void signInWithFirebase(AuthCredential credential) {
mFirebaseAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
getFirebaseToken();
} else {
Utils.showDialogMessage(mContext, task.getException().getLocalizedMessage());
}
}
});
}
Google says the step 2 is merging because after signed in, you need to get information of the previous user and put into the new user.
I hope it helpful.
When creating a user, I want to be able to set his/her display name. How do I do this in Android? Here is an example of what I want to achieve:
mAuth.createUserWithEmailAndPassword(email, password).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
FirebaseUser.getCurrentUser().setDisplayName(mName); //I want to do this
}
});
Assume all variables have been declared and/or initialized correctly.
You can set the user's Firebase display name by writing the following three lines of code:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(mName).build();
user.updateProfile(profileUpdates);
By doing so, your original code should look like this:
mAuth.createUserWithEmailAndPassword(email, password).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
// Sign in is successful
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(mName).build();
user.updateProfile(profileUpdates)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "User profile updated.");
}
}
});
}
});
Official Firebase Documentation:
Firebase Update a User's Profile
What the above code does is that when the user's account is successfully created using Email and Password authentication, it will then sign-in the user.
Once the user is signed-in, you can access the user's Firebase User Object Properties and set the display name property to any string you want.
This is great for testing the user's profile name in Verification Emails.
Note: A Firebase User Object has a fixed set of basic properties—a unique ID, a primary email address, a name, and a photo URL. These basic properties are stored in the project's User Database.
Furthermore, these properties can be updated programmatically.
However, you cannot add other properties to the Firebase User Object directly; instead, you can store any additional properties (i.e. user information) in your Firebase Realtime Database, and reference them from there.
(Firebase User Object Properties Doc)
I found the answer in the Firebase docs. I will quote it here: "If sign-in succeeded, the AuthStateListener runs the onAuthStateChanged callback. In the callback, you can use the getCurrentUser method to get the user's account data." Here is the link: https://firebase.google.com/docs/auth/android/password-auth#sign_in_a_user_with_an_email_address_and_password
So that means, if you do the above code (minus the FirebaseUser line), and then declare and initialize a Firebase AuthStateListener like shown below, you can set the user's display name and then move on to any other activity you want:
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if(user!=null){
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(mName).build();
user.updateProfile(profileUpdates);
Intent intent = new Intent(currentActivity.this, nextActivity.class);
startActivity(intent);
}
}
};
And don't forget to add the AuthStateListener in onResume() like so:
#Override
public void onResume(){
super.onResume();
mAuth.addAuthStateListener(mAuthListener);
}
Likewise, don't forget to remove it in the onStop method like so:
#Override
public void onStop(){
super.onStop();
if(mAuthListener != null){
mAuth.removeAuthStateListener(mAuthListener);
}
}
And done! You set the user's display name so you can use it in other activities. This would be useful if you want to greet the user or access any other user data tied to the display name.
I've created a Chat function on my android app, but I wanted my users to be able to create an account. However, I managed to let users create an account using Firebase. But the problem is that it allows you to create accounts with Facebook etc, I choose for email and password. This doesn't allow you to set an username, I believe so. Maybe there's a way to change the UID?
If anyone is able to help me out here, I'd be so thankful!
Again, I'm trying to let the user create an username too.
Have a look at the FirebaseUI implementation of its Email+Password registration flow:
firebaseAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
final FirebaseUser firebaseUser = task.getResult().getUser();
Task<Void> updateTask = firebaseUser.updateProfile(
new UserProfileChangeRequest
.Builder()
.setDisplayName(name).build());
updateTask.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
mActivityHelper.dismissDialog();
if (task.isSuccessful()) {
startSaveCredentials(firebaseUser, password);
}
}
});
}
Alternatively, you might simple want to use FirebaseUI, which encapsulates this and many other auth flows.