How Firebase defines current user in Auth? - java

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.

Related

Tried to add a new field of data to Firebase user when registering, but no update X method in FirebaseUser.class file

I am using the Realtime database, so the users are store in the database. I am attempting to implement a 'currentLocation' field for the FirebaseUser objects so that I can eventually create a list for each user of nearby users. I was already using a HashMap to input the data, so I just added hashmap.put('currentLocation', ''); to create an empty current location field that can be updated later.
Unfortunately though I cannot find a way to set/update the currentLocation field as there is no updateCurrentLocation() method in the FirebaseUser.class. How do I add this method to this read-only file? Is this even the best way to do this?
Code:
//Dashboard.java
usedLocationClient.getLastLocation()
.addOnSuccessListener(this, new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
// Got last known location. In some rare situations this can be null.
if (location != null) {
// Logic to handle location object
//get current user
final FirebaseUser fUser = FirebaseAuth.getInstance().getCurrentUser();
//Updates the firebase db user with their current location.
fUser.updateCurrentLocation(location);
//This method is not in the firebaseuser.class file but needs to be!
//fUser.updateCurrentLocation(location);
}
}
});
//RegisterActivity.java
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// Sign in success, dismiss dialog and start register activity
progressDialog.dismiss();
FirebaseUser user = mAuth.getCurrentUser();
//Get user email and uid from auth
String email = user.getEmail();
String uid = user.getUid();
//When user is registered store user info in firebase realtime database too
//using HashMap
HashMap<Object, String> hashMap = new HashMap<>();
//put info in hasmap
hashMap.put("email", email);
hashMap.put("uid", uid);
hashMap.put("name", ""); //will add later (e.g. edit profile)
hashMap.put("currentLocation", "");
hashMap.put("onlineStatus", "online"); //will add later (e.g. edit profile)
hashMap.put("typingTo", "noOne"); //will add later (e.g. edit profile)
hashMap.put("phone", ""); //will add later (e.g. edit profile)
hashMap.put("image", ""); //will add later (e.g. edit profile)
hashMap.put("cover", ""); //will add later (e.g. edit profile)
//firebase database instance
FirebaseDatabase database = FirebaseDatabase.getInstance();
//path to store user data named "Users"
DatabaseReference reference = database.getReference("Users");
//put data within hashmap in database
reference.child(uid).setValue(hashMap);
Toast.makeText(RegisterActivity.this, "Registered...\n"+user.getEmail(), Toast.LENGTH_SHORT).show();
startActivity(new Intent(RegisterActivity.this, DashboardActivity.class));
finish();
//FirebaseUser.class Bytecode
#NonNull
public Task<Void> updateEmail(#NonNull String email) {
Preconditions.checkNotEmpty(email);
return FirebaseAuth.getInstance(this.zza()).zzn(this, email);
}
#NonNull
public Task<Void> updatePassword(#NonNull String password) {
Preconditions.checkNotEmpty(password);
return FirebaseAuth.getInstance(this.zza()).zzo(this, password);
}
#NonNull
public Task<Void> updatePhoneNumber(#NonNull PhoneAuthCredential credential) {
return FirebaseAuth.getInstance(this.zza()).zzp(this, credential);
}
#NonNull
public Task<Void> updateProfile(#NonNull UserProfileChangeRequest request) {
Preconditions.checkNotNull(request);
return FirebaseAuth.getInstance(this.zza()).zzq(this, request);
}
FirebaseUser class, has only a few fields that are related to the authentication. If you need more details about your users, you should create a POJO class to store additional data.
This data can be stored either in Cloud Firestore or in the Realtime Database so it can be later used.
Please also note, the Realtime Database doesn't store null values. Firestore does.
To update the location of the current user, you can do:
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference reference = database.getReference("Users");
reference.child(uid).child("currentLocation").setValue("the location");
Since you mention wanting to find nearby users, I recommend checking out: Query for nearby locations and https://github.com/firebase/geofire-android/

validate existing user's mobile number in firebase

I have a firebase project which allows users to login only if they are already exists in identifier in authentication .
I already added few users using my web app with mobile numbers.
Now, in android I have used the signInWithPhoneAuthCredential method to get the users login.
But in this method, it allows any users to login even if the user is first time entering the mobile number.
Is there any method to restrict this ?
Sample Code :
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
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
Log.d(TAG, "signInWithCredential:success");
FirebaseUser user = task.getResult().getUser();
// ...
} else {
// Sign in failed, display a message and update the UI
Log.w(TAG, "signInWithCredential:failure", task.getException());
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
// The verification code entered was invalid
}
}
}
});
}
According to the docs:
signInWithPhoneNumber:
Asynchronously signs in using a phone number. This method sends a code via SMS to the given phone number, and returns a firebase.auth.ConfirmationResult. After the user provides the code sent to their phone, call firebase.auth.ConfirmationResult.confirm with the code to sign the user in.
This is the default behavior in all applications that uses phone number as login. There is no method in the firebase docs that can restrict this.
you have to use firebase database also with this code to save user info, that way you can achieve your use case

.getCurrentUser() never returns null - firebase

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);

Get user's displayname in firebase function once account is created

I have an Android app where the user registers for an account with their email, password, and displayName. I want to send a welcome email to the user after they create an account. This is how I create my account and set their display name.
// This happens in Android (RegisterActivity.java) where I create user's account
FirebaseAuth auth = FirebaseAuth.getInstance();
auth.createUserWithEmailAndPassword(email, password)
.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
#Override
public void onSuccess(AuthResult authResult) {
FirebaseUser user = authResult.getUser();
user.updateProfile(new UserProfileChangeRequest.Builder()
.setDisplayName(name).build());
}
});
Once the user's account is created, a firebase function is triggered. Below is my code:
// This happens in Firebase Cloud Functions (index.js)
exports.sendWelcomeEmail = functions.auth.user().onCreate((user) => {
// send welcome email here
console.log(user.displayName) // displayName is null here
});
I believe that the firebase function gets triggered as soon as the account creation is successful, and I set user's displayname after the account is created and so displayName is null in the function. What can I do to solve the issue? I don't want to send an email to the user without their name in the email.
tl;dr: displayName is being called before is being set.
The onCreate function runs after the front end finishes createUserWithEmailAndPassword but before the displayName is set.
Either you run an onCall function after you update the displayName or as suggested on the firebase github thread on this issue you can add a profile parameter to the createUserWithEmailAndPassword so that we create new accounts with a pre-populated profile.

How to create unique token, in every users firebase android?

I want to generate and store token everytime users login. I tried for my code below, but it always generate same token when I login with another account.
mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(LoginActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
AlertDialog.dismiss();
if (!task.isSuccessful()) {
if (password.length() < 6) {
new SweetAlertDialog(LoginActivity.this, SweetAlertDialog.ERROR_TYPE)
.setTitleText("Oops...")
.setContentText("Enter minimum 6 charachters !! ")
.show();
} else {
passwordInput.setText("");
new SweetAlertDialog(LoginActivity.this, SweetAlertDialog.ERROR_TYPE)
.setTitleText("Oops...")
.setContentText("Authentication failed !!")
.show();
}
} else {
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
FirebaseUser users = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference("users/"+ users.getUid());
String token = FirebaseInstanceId.getInstance().getToken();
Log.e("tokenid",""+token);
mDatabase.child("token_id").setValue(token);
finish();
}
}
});
}
});
please help, thanks..
When using the following line of code:
String token = FirebaseInstanceId.getInstance().getToken();
You are getting the Firebase Instance ID token, which is also known as FCM token, on the client side. You need to know that in Firebase there two different tokens:
A FCM Token/Instance ID token that identifies an installation of a specific application on a specific user device. It doesn't identify in any way a particular user.
An Auth ID token identifies a specific user of a specific application. It doesn't identify in any way a particular device.
The two tokens are quite different and serve different purposes. Please see the official documentation for Android regarding on how to retrieve ID tokens on clients.
The identity of the user is remembered indefinitely (or until you sign out). But their credentials (or rather, whether their token is still valid) are re-checked every hour.
FCM generates a registration token for the client app instance, hence It may happen that you'll get the same token for different users in your app. You can use forceRefresh to generate a new token every time. Register new token everytime user logins to any device and save it in DB and update with a new token on new login this way you will have a new token for each user on every login (If this fits your requirement)
Here is a good answer to understand how it works Firebase FCM force onTokenRefresh() to be called
Use UUID.randomUUID().toString()
You can read more here.
java docs - and here =)

Categories

Resources