I need to detect and differentiate two users using Firebase phone authentication . This should be done before granting a privilege to enter into the home activity of the app. When I did as suggested here (Stackoverflow) , it does well by detecting the user using timeStamp()
method. The answer does its job but the fancy thing is I need some data input from the new user before the verification code is sent.
In order for a verification code to be sent, a user provides a number which is directly authenticated in the firebase
. Hence I cannot check if it's a new user
(phone number) or current user
(phone number).
Here is the code using TimeStamp()
method.
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential)
{
_firebaseAuth.signInWithCredential(credential).addOnCompleteListener(Objects.requireNonNull(getActivity()), task ->
{
if(task.isSuccessful())
{
//Sign in success, update UI with the signed-in user's information.
FirebaseUser _user = Objects.requireNonNull(task.getResult()).getUser();
long creationTimestamp = Objects.requireNonNull(Objects.requireNonNull(_user).getMetadata()).getCreationTimestamp();
long lastLoginTimestamp = Objects.requireNonNull(Objects.requireNonNull(_user).getMetadata()).getLastSignInTimestamp();
if(creationTimestamp == lastLoginTimestamp)
{
//Create a new user with account
setUserDataToDatabase(_user, _username, _university, _course, _year);
sendUserToWelcome();
}
else
{
//User exists, just login
sendUserToHome();
}
}
else
{
FancyToast.makeText(getContext(), "Enter sent code", FancyToast.LENGTH_SHORT, FancyToast.INFO, false).show();
}
});
}
After several research with no success. I decided to walk around, I'm using firestore database
. I decided to track every user's number in a new collection
with auto-generated document id
. I called the collection USERS
whereas each document
has a unique random id.
I get the user's number and check it if any of the registered user has that number with the USERS
's collection using a whereEqualTo()
method with the phone_number
field. If
the number is exists I login the user else
display a registration screen.
_firestore.collection(USERS).whereEqualTo("phone_number", _phoneCheck).get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>()
{
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task)
{
if(task.isSuccessful())
{
//If task is greater than 0 means there is a presence of a phone number.
if(Objects.requireNonNull(task.getResult()).size() > 0)
{
//Here I allow user to login as usual.
PhoneAuthOptions options = PhoneAuthOptions.newBuilder(_firebaseAuth).setPhoneNumber(_phone).setTimeout(60L, TimeUnit.SECONDS).setActivity(Objects.requireNonNull(getActivity())).setCallbacks(_callbacks).build();
PhoneAuthProvider.verifyPhoneNumber(options);
}
}
else
{
//Else the task is empty means there is no a presence of a phone number.
//Check if there is a presence of registration data to bind with new user.
if(_registrationData != null)
{
//I login user with the new data and save the information into the firestore plus the phone number.
PhoneAuthOptions options = PhoneAuthOptions.newBuilder(_firebaseAuth).setPhoneNumber(_phone).setTimeout(60L, TimeUnit.SECONDS).setActivity(Objects.requireNonNull(getActivity())).setCallbacks(_callbacks).build();
PhoneAuthProvider.verifyPhoneNumber(options);
userInputs();
}
else
{
//Display a welcome a screen to register an account.
FancyToast.makeText(getContext(), "Welcome! Open an account", FancyToast.LENGTH_SHORT, FancyToast.INFO, false).show();
}
}
}
}
});
Allowing unauthenticated user to have a privilege into the database is very risk. Hence, I implemented a rule to allow unauthenticated user to read only.
match /USERS/{document=**}
{
allow read: if true;
}
Though this still is risky, any rule suggestions I will be grad and appreciable.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.