Firebase Auth emailVerified doesn't updated - android

hi guys i'm trying to do auto login in my app but before login done i wonder if the user verified his email or no.
the problem : even if i verified my account the code doesn't see this and said false.
and here is my code.
class SignInActivity : BaseActivity<SignInViewModel, ActivitySignInBinding>(), Navigator {
private lateinit var preferenceManger: PreferenceManger
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
preferenceManger = PreferenceManger(applicationContext)
autoLogin()
binding.vm = viewModel
viewModel.navigator = this
addPrefManger()
}
private fun autoLogin() {
DataUtils.firebaseUser = Firebase.auth.currentUser
if (preferenceManger.getBoolean(Constants.KEY_IS_SIGNED_IN)) {
when {
DataUtils.firebaseUser!!.isEmailVerified -> {
startActivity(Intent(this, HomeActivity::class.java))
finish()
}
else -> {
startActivity(Intent(this, VerificationActivity::class.java))
finish()
}
}
}
}
this line is always false even if i verified my account.
DataUtils.firebaseUser!!.isEmailVerified

While the verification status of the user profile is updated on the server as soon as they've clicked the link, it may take up to an hour before that information is synchronized to the Android app.
If you want to detect the email verification in the app before it is automatically synchronized, you can:
Sign the user out and in again.
Force reloading of the user profile (after the user has clicked the link) by calling reload on the user object. You can put a button in your UI to do this, or automatically call that, for example in the onResume of the activity.
Also see:
How to verify email without the need of signing in again while using FirebaseUI-auth?
Verification email activity not refreshing

Related

FIrebase sign in and out options are not working

Can someone explain to me why this simple code is not working properly?
In the beginning I created an object with auth and currentUser
object FirebaseUtils {
val auth: FirebaseAuth = FirebaseAuth.getInstance()
val currentUser: FirebaseUser? = auth.currentUser
}
My login activity function
fun login(){
val email = binding.loginInput.text.toString()
val password = binding.passwordInput.text.toString()
auth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener {
task ->
if (task.isSuccessful){
task.result
Log.d("login_status", "Logged: ${currentUser?.uid}")
startActivity(Intent(this, MainActivity::class.java))
finish()
} else {
Log.d("login_status", task.exception.toString())
}
}
}
Start activity:
lifecycleScope.launch {
delay(2000)
if(currentUser?.uid != null){
Log.d("login_status", "Logged: ${currentUser.uid}")
startActivity(Intent(applicationContext, MainActivity::class.java))
}else{
startActivity(Intent(applicationContext, LoginMainActivity::class.java))
}
finish()
}
And sign out
fun signOut(){
auth.signOut()
startActivity(Intent(this, LoginMainActivity::class.java))
Log.d("login_status", "Signed out: ${currentUser?.uid}")
finish()
}
The problem is that after the first login I can see that logged user is null so my app is crashing (no data for the user). However, after restarting I am logged in as this user. I cant also sign out - activity changes to the login screen but even if I pass different credentials the user remains the same.
EDIT
When I log in and restart the app it works - the correct user is logged.
When I log out and restart the app it also works - the user is signed out.
So why is there a problem between activities
Your result is null because you are getting the result object out of the task object but you aren't doing anything with it. Simply calling:
task.result
Doesn't provide any benefit. However, you can save that result into a variable and call AuthResult#getUser() like this:
val user = task.result.getUser()
Log.d("login_status", "Logged: ${user?.uid}")
So right after you authenticate the user successfully, you'll be able to log the UID correctly.

Android add hook into firebase email auth to replace "sign-in email sent" screen

Am using Firebase Auth in Kotlin to trigger email link sign-in. It's all working fine, but I would like to change the "Sign-in email sent" screen with a custom one but cant find an event/callback that is triggered when this UI is displayed so I can detect this and replace it.
Excerpt of relevant code
private val signInActivity = registerForActivityResult(FirebaseAuthUIActivityResultContract()) { result ->
}
private fun emailSignIn() {
signInActivity.launch(FirebaseSignInHelper.createSignInForEmailIntent().build())
}
class FirebaseSignInHelper {
companion object {
fun createSignInForEmailIntent() = createSignInIntent(emailProvider())
private fun createSignInIntent(providers: List<AuthUI.IdpConfig>) =
AuthUI.getInstance()
.createSignInIntentBuilder()
.setIsSmartLockEnabled(!BuildConfig.DEBUG, true)
.setAvailableProviders(providers)
.setLogo(R.drawable.black_crown_with_name)
.enableAnonymousUsersAutoUpgrade()
.setTheme(R.style.GreenTheme)
private fun actionCodeSettings() =
ActionCodeSettings.newBuilder()
.setAndroidPackageName("<domain>", false, null)
.setHandleCodeInApp(true) // This must be set to true
.setUrl("<url>") // This URL needs to be whitelisted
.build();
fun emailProvider() =
arrayListOf(
AuthUI.IdpConfig.EmailBuilder()
.enableEmailLinkSignIn()
.setActionCodeSettings(actionCodeSettings())
.build()
)
}
}
I have tried Subclassing FirebaseAuthUIActivityResultContract and implementing available overrides and as it all runs in its own activity I can't find a way to hook into activity life cycle or callback events, unless someone knows how to do this? Nothing seems to work, the app is just left on this screen with nothing in code to tell me this.

email is not verified

in my application first i authenticate user email and then i am verifying user email i have set dialog activity to inform user to check email and verify email i have close button in dialog activity if user click on it dialog will be dismissed
i have implemented override fun onResume() method first activity and in this method i check user have verified email or not by auth.getInstance().currentUser.isEmailVerified
i ran this app i got email and successfully verify but in onResume() method auth.getInstance().currentUser.isEmailVerified returns false
auth.createUserWithEmailAndPassword(binding.email.text.toString(),binding.password.text.toString()).addOnCompleteListener { task->
Log.d("userAuthenticated","yes")
if(task.isSuccessful)
{
val currUser=auth.currentUser
Log.d("TaskIsSuccessful","Yes")
currUser!!.sendEmailVerification().addOnSuccessListener {
Log.d("Emailissent","yes")
uniqueFirebaseAuthId=task.result!!.user!!.uid.toString()
val sentEmailbinding=ActivityEmailVarificationSignUpBinding.inflate(layoutInflater)
val dialog = Dialog(this#SignUp)
dialog.setContentView(sentEmailbinding.root)
dialog.setCanceledOnTouchOutside(true)
dialog.setCancelable(false)
sentEmailbinding.closebtn.setOnClickListener{
dialog.dismiss()
Log.d("Iamback","Yes")
}
dialog.show()
Log.d("verified",currUser.isEmailVerified.toString())
Log.d("Dialogshown","yes")
Log.d("uniqueFirebaseAuthValue","${uniqueFirebaseAuthId} ")
}.addOnFailureListener {
Log.d("emailauthverification",it.toString())
}
}
task.addOnFailureListener {
Log.d("TaskFail",it.toString())
}
onResume() function
override fun onResume() {
super.onResume()
val userEnterdName=binding.uiqueusername.toString()
val currUser=FirebaseAuth.getInstance().currentUser
if(currUser!!.isEmailVerified) {
val verifiedUser=UseratFirebase(userEnterdName,binding.email.toString(),binding.password.toString())
val uniqueAuthId=uniqueFirebaseAuthId.toString()
database.reference.child("users").child(uniqueAuthId).setValue(verifiedUser).addOnSuccessListener {
val intent=Intent(this#SignUp,SignIn::class.java)
intent.putExtra("Email",binding.email.text.toString())
intent.putExtra("password",binding.email.toString())
}.addOnFailureListener {
Toast.makeText(this#SignUp,"Error occured while stroting data",Toast.LENGTH_LONG).show()
}
}
else
{
Log.d("Curruser", "${currUser.toString() } -> ${currUser.isEmailVerified}")
Toast.makeText(this#SignUp,"Please verify Your Account",Toast.LENGTH_LONG).show()
}
}
Verifying the user's email address happens in another application (you click the link in your mail app, and then it verifies that action in the browser), so you app is not aware of it right away.
The information is encoded in the user's ID token, which is refreshed automatically every hour, or when the user signs in again. So you can either wait/force the user to sign in again, or you can tell the SDK to refresh the token by calling user.getIdToken(true) or user.reload().

Android Facebook Login. Prevent button from changing to "log out"

Let me describe the application im trying to do using Kotlin, on Android Studio.
Splash Screen => Login Screen => Main App
Splash Screen: Just a photo
Login Screen: Provides different ways of logging (Google, Facebook, etc)
MainActivity: Allows you to log off, in that case, you must return to "Login Screen"
So far I have been working only with Facebook Login.
I managed to place the button, make it work, and get a proper uid. The trouble is that, when that button is clicked, it automatically switches to "Log Out". So, when I go back from my MainActivity to my Login Screen, instead of having the button to Login again, im having a "Log Out" button, when account is actually already logged out.
Is there a way to prevent this button from changing? I have been reading tons of documentation, but havent found anything useful.
Is my idea incorrect? Or is there a better way to do this?
Note that everytime I Leave the LoginScreen, I place a finish(). The reason of this was to try to reset the activity, and make it work as if the program was running from scratch.
Variables defined on LoginScreen
private var mCallBackManager : CallbackManager?= null
private var mFirebaseAuth : FirebaseAuth?= null
On create function
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.lay_login_screen)
//-----------Inicializadores-Facebook---------------
mFirebaseAuth = FirebaseAuth.getInstance()
FacebookSdk.sdkInitialize(getApplicationContext())
mCallBackManager = CallbackManager.Factory.create()
//--------------------------------------------------
//-----------Boton-Facebook-------------------------
Button_LoginScreen_LoginFace.setOnClickListener()
{
iniciarSesionFacebook();
}
//--------------------------------------------------
}
private fun iniciarSesionFacebook()
{
Button_LoginScreen_LoginFace.registerCallback(mCallBackManager, object : FacebookCallback<LoginResult>
{
override fun onSuccess(result: LoginResult?)
{
d(getString(R.string.TAG_FacebookLogin),"Login Correct")
handleFacebookToken(result!!.accessToken)
}
override fun onCancel()
{
d(getString(R.string.TAG_FacebookLogin),"Login cancelled")
}
override fun onError(error: FacebookException?)
{
d(getString(R.string.TAG_FacebookLogin),"Login Error")
}
})
}
private fun handleFacebookToken(accessToken: AccessToken?)
{
val credential = FacebookAuthProvider.getCredential(accessToken!!.token)
mFirebaseAuth!!.signInWithCredential(credential).addOnFailureListener()
{error->
d(getString(R.string.TAG_FacebookLogin),"Error 1"+error.message)
}
.addOnSuccessListener { resultado->
startActivity(Intent(this, MainActivity::class.java))
finish()
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?)
{
super.onActivityResult(requestCode, resultCode, data)
mCallBackManager!!.onActivityResult(requestCode,resultCode,data)
}
Finally, this is how I "Log Out" from MainActivity, and return to LoginScreen
class MainActivity : AppCompatActivity()
{
//----------Variables-Globales----------------
private var mFirebaseAuth : FirebaseAuth?= null
//--------------------------------------------
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//-------Inicializo-Variables------------------------
mFirebaseAuth = FirebaseAuth.getInstance()
//---------------------------------------------------
Button_MainActity_LogOf.setOnClickListener{
val firebaseaux=mFirebaseAuth
firebaseaux?.signOut()
startActivity(Intent(this, ActivityLoginScreen::class.java))
}
}
}
This is how the LoginScreen looks the first time is ran.
This is how it looks after manually logging of. Note that is not only the appearence of the code, the code itself changes. Now the button doesnt allow you to LogIn.
Just to add some extra information, i have found this property on the docs
Configuration: auto_logout_link
HTML5 Attribute: data-auto-logout-link
Description: If its activated, the button will be replaced by a LogOut button if the user has already logged in
Options: True,False
This es EXACTLY what im looking for. But, from what I can see, that is only ment for webpages and not android. Does somebody know how to touch this configuration in android? or the equivalent adroid option?
I will add the link where I found the property.
https://developers.facebook.com/docs/facebook-login/web/login-button/
Thanks in advance
Ok, after some time I managed to solve the Issue.
I was logging out from the Firebase Authentication, but not from Facebook authentication.
I didnt manage to stop the button from behaving like it does, but at least the behaviour now is correct.
I will share my new LogOut code.
Button_MainActity_LogOf.setOnClickListener{
FirebaseAuth.getInstance().signOut() //Log out from Firebase
if(isFacebookLogin()) //Check if logged in on facebook
{
LoginManager.getInstance().logOut() //Log out from facebook
}
//Here i should log out from other providers
startActivity(Intent(this, ActivityLoginScreen::class.java))
}
private fun isFacebookLogin(): Boolean
{
return AccessToken.getCurrentAccessToken() !=null
}

Firebase authentication after user had been deleted

I have an android application which uses Firebase Authentication via Facebook. A user can delete their account in the application using the following function:
override fun deleteUserAcc() {
val user = FirebaseAuth.getInstance().currentUser
val userToken = FacebookAuthProvider.getCredential(authTokenProvider.provideToken())
user?.reauthenticate(userToken)?.addOnCompleteListener { task ->
user.delete()
}
}
After this a user really gets deleted on the Firebase servers. However when they try to access the application again and log in one more time, they are not able to do this (their account with uid had been deleted and somehow they are not assigned a new one uid).
The login function and the onSuccess callback are both implemented and called.
override fun login(): Completable {
LoginManager.getInstance().logInWithReadPermissions(
activityReference.get(),
listOf("public_profile", "user_birthday", "user_location")
)
return CompletableSubject.create().apply {
loginSubject = this
}
}
override fun onSuccess(result: LoginResult) {
val credential = FacebookAuthProvider.getCredential(result.accessToken.token)
authTokenProvider.saveToken(result.accessToken.token)
firebaseAuth.signInWithCredential(credential)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
getInfoOnFirestore(loginSubject)
} else {
loginSubject.onError(task.exception!!)
}
}
}
What can possibly be the cause of the following issue?
A little late to the party but I know what the issue is. Firebase deletes only the authentication, which means that the real-time database is still there with the same uid. In order to delete the database entry as well, you need to upgrade to the blaze program and add the extension.

Categories

Resources