为啥即使电子邮件经过验证,电子邮件验证仍然存在?

Posted

技术标签:

【中文标题】为啥即使电子邮件经过验证,电子邮件验证仍然存在?【英文标题】:Why email verification still present even the email is verified?为什么即使电子邮件经过验证,电子邮件验证仍然存在? 【发布时间】:2021-10-04 17:07:26 【问题描述】:

我目前正在开发一个移动应用程序作为我最后一个学期的项目。在我的移动应用程序中,我使用 firebase 身份验证进行此电子邮件验证。这是我执行此功能的教程(如果您有兴趣)。

Firebase Login & Register App With Email | Part - 8 | Verify Email Address

我的问题是当我在我的移动应用程序中添加重置密码功能(教程的下一部分)时,即使电子邮件已验证,电子邮件验证警报仍然存在。

SETTINGS Activity(找到重置密码和邮箱验证功能的地方)

package com.example.biowit;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;

public class Settings extends AppCompatActivity 

Button Back_ST_btn, AboutUs_btn, VerEmail_btn, Res_Pass_btn, Con_Res_btn, Cancel_Res_btn;
TextView VerEmail_txt;
EditText NewPass_input, CoNewPass_input;
FirebaseAuth set_FbAuth;
FirebaseUser set_FbUser;
String respass_set, conpass_set;
// Switch Music_swch;

@Override
protected void onCreate(Bundle savedInstanceState) 

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_settings);

    AboutUs_btn = findViewById(R.id.btn_AboutUs);
    Back_ST_btn = findViewById(R.id.btn_ST_Back);
    Res_Pass_btn = findViewById(R.id.btn_Reset_Pass);
    Con_Res_btn = findViewById(R.id.btn_Confirm_Reset);
    Cancel_Res_btn = findViewById(R.id.btn_Cancel_Reset);
    NewPass_input = findViewById(R.id.txt_New_Pass);
    CoNewPass_input = findViewById(R.id.txt_CoNew_Pass);
    VerEmail_btn = findViewById(R.id.btn_Verify_Email);
    VerEmail_txt = findViewById(R.id.lbl_Verify_Email);
    // Music_swch = findViewById(R.id.swch_ST_Music);.
    
    set_FbAuth = FirebaseAuth.getInstance();
    set_FbUser = set_FbAuth.getCurrentUser();


    Res_Pass_btn.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 

            NewPass_input.setVisibility(View.VISIBLE);
            CoNewPass_input.setVisibility(View.VISIBLE);
            Con_Res_btn.setVisibility(View.VISIBLE);
            Cancel_Res_btn.setVisibility(View.VISIBLE);
        
    );

    Cancel_Res_btn.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            NewPass_input.setVisibility(View.GONE);
            CoNewPass_input.setVisibility(View.GONE);
            Con_Res_btn.setVisibility(View.INVISIBLE);
            Cancel_Res_btn.setVisibility(View.INVISIBLE);
        
    );

    Con_Res_btn.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            
            respass_set = NewPass_input.getText().toString();
            conpass_set = CoNewPass_input.getText().toString();

            if(respass_set.isEmpty()) // condition if new password field is empty, error message will be shown.
                NewPass_input.setError("This field cannot be empty.");
                return;
            

            if(conpass_set.isEmpty()) // condition if confirm password field is empty, error message will be shown.
                CoNewPass_input.setError("This field cannot be empty.");
                return;
            

            if (!conpass_set.equals(respass_set)) // condition if the confirm password is not equals to new password, error message will be shown.
                CoNewPass_input.setError("Password does not match.");
                return;
            

            set_FbUser.updatePassword(respass_set).addOnSuccessListener(new OnSuccessListener<Void>() 

                @Override
                public void onSuccess(Void unused) 

                    Toast.makeText(getApplicationContext(),"New Password saved.", Toast.LENGTH_LONG).show();
                    NewPass_input.setVisibility(View.GONE);
                    CoNewPass_input.setVisibility(View.GONE);
                    Con_Res_btn.setVisibility(View.INVISIBLE);
                
            ).addOnFailureListener(new OnFailureListener() 

                @Override
                public void onFailure(@NonNull Exception e) 

                    Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
                
            );
        
    );

    //When email is not verified, a message and button will appear.
    if (!set_FbAuth.getCurrentUser().isEmailVerified())

        VerEmail_txt.setVisibility(View.VISIBLE);
        VerEmail_btn.setVisibility(View.VISIBLE);
    

    //When the "Verify Now" button is clicked, it will send a verification email to the user's email address.
    VerEmail_btn.setOnClickListener(new View.OnClickListener() 

        @Override
        public void onClick(View v) 

            //send verificaiton email
            set_FbAuth.getCurrentUser().sendEmailVerification().addOnSuccessListener(new OnSuccessListener<Void>() 

                @Override
                public void onSuccess(Void unused) 
                    Toast.makeText(getApplicationContext(),"Verification Email sent.", Toast.LENGTH_LONG).show();
                    VerEmail_txt.setVisibility(View.GONE);
                    VerEmail_btn.setVisibility(View.GONE);
                
            );
        
    );
    
    Back_ST_btn.setOnClickListener(new View.OnClickListener() 

        @Override
        public void onClick(View v)  // returns to previous screen.

            finish();
        
    );

    AboutUs_btn.setOnClickListener(new View.OnClickListener() 

        @Override
        public void onClick(View v) 
            startActivity(new Intent(getApplicationContext(), AboutUsScreen.class));
        
    );


public void PlayBackgroundSound(View view)

    startService(new Intent(this, BgMusicService.class));



这是错误日志

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.biowit, PID: 7789
java.lang.RuntimeException: Unable to start activity ComponentInfocom.example.biowit/com.example.biowit.HomeScreen: java.lang.IllegalStateException: Not allowed to start service Intent  cmp=com.example.biowit/.BgMusicService : app is in background uid UidRecord964c600 u0a2 TPSL idle change:cached procs:1 seq(0,0,0)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3754)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3912)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2319)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:239)
    at android.app.ActivityThread.main(ActivityThread.java:8212)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:626)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1016)
 Caused by: java.lang.IllegalStateException: Not allowed to start service Intent  cmp=com.example.biowit/.BgMusicService : app is in background uid UidRecord964c600 u0a2 TPSL idle change:cached procs:1 seq(0,0,0)
    at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1758)
    at android.app.ContextImpl.startService(ContextImpl.java:1698)
    at android.content.ContextWrapper.startService(ContextWrapper.java:720)
    at android.content.ContextWrapper.startService(ContextWrapper.java:720)
    at com.example.biowit.HomeScreen.onCreate(HomeScreen.java:35)
    at android.app.Activity.performCreate(Activity.java:8119)
    at android.app.Activity.performCreate(Activity.java:8103)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1359)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3727)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3912) 
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) 
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2319) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loop(Looper.java:239) 
    at android.app.ActivityThread.main(ActivityThread.java:8212) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:626) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1016) 
Disconnected from the target VM, address: 'localhost:53820', transport: 'socket'

这是设置中的图片

我这里用来登录的邮箱在添加重置密码功能之前已经过验证。

如您所见,存在电子邮件验证警报。

【问题讨论】:

【参考方案1】:

用户对象被缓存,这包括验证信息。因此,您需要将更改通知客户端,使用 java,这是通过任务完成的

带有一个 sendEmailVerification() 方法,它作为 Task 返回,用于异步发送电子邮件,并报告状态。

例如:

final FirebaseUser user = mAuth.getCurrentUser();
        user.sendEmailVerification()
                .addOnCompleteListener(this, new OnCompleteListener() 
                    @Override
                    public void onComplete(@NonNull Task task) 
                        // Re-enable button
                        findViewById(R.id.verify_email_button).setEnabled(true);

                        if (task.isSuccessful()) 
                            Toast.makeText(EmailPasswordActivity.this,
                                    "Verification email sent to " + user.getEmail(),
                                    Toast.LENGTH_SHORT).show();
                         else 
                            Log.e(TAG, "sendEmailVerification", task.getException());
                            Toast.makeText(EmailPasswordActivity.this,
                                    "Failed to send verification email.",
                                    Toast.LENGTH_SHORT).show();
                        
                    
                );

从mAuth.getCurrentUser()中获取用户,调用sendEmailVerification()方法。

您可以在此处找到完整指南:https://firebase.googleblog.com/2017/02/email-verification-in-firebase-auth.html

【讨论】:

以上是关于为啥即使电子邮件经过验证,电子邮件验证仍然存在?的主要内容,如果未能解决你的问题,请参考以下文章

PHPMailer 使用 SMTP 身份验证发送电子邮件,但 Gmail 仍然声称它无法验证发件人

即使经过验证,AWS SES 电子邮件也总是会进入垃圾邮件

邮件表单提交,即使验证失败

为啥电子邮件验证总是在我的应用程序中出错? [复制]

保护Exchange OWA免受暴力***

我无法登录。即使我在Firebase中输入了电子邮件和密码,它仍然会保持Saying Error Logging