在 Android 上使用基于密码的账户进行 Firebase 身份验证

您可以借助 Firebase Authentication 让您的用户使用其电子邮件地址和密码进行 Firebase 身份验证,还可以管理您的应用的基于密码的账号。

准备工作

  1. 将 Firebase 添加到您的 Android 项目(如果尚未添加)。

  2. 如果您尚未将应用关联至您的 Firebase 项目,请从 Firebase 控制台执行此操作。
  3. 启用电子邮件地址/密码登录方法:
    1. Firebase 控制台中,打开 Auth 部分。
    2. 登录方法标签页中,启用电子邮件地址/密码登录方法,然后点击保存
  4. 模块(应用级)Gradle 文件(通常是 <project>/<app-module>/build.gradle.kts<project>/<app-module>/build.gradle)中,添加 Firebase Authentication 库的依赖项。我们建议使用 Firebase Android BoM 来实现库版本控制。

    dependencies {
        // Import the BoM for the Firebase platform
        implementation(platform("com.google.firebase:firebase-bom:33.4.0"))
    
        // Add the dependency for the Firebase Authentication library
        // When using the BoM, you don't specify versions in Firebase library dependencies
        implementation("com.google.firebase:firebase-auth")
    }
    

    借助 Firebase Android BoM,可确保您的应用使用的始终是 Firebase Android 库的兼容版本。

    (替代方法) 在不使用 BoM 的情况下添加 Firebase 库依赖项

    如果您选择不使用 Firebase BoM,则必须在每个 Firebase 库的依赖项行中指定相应的库版本。

    请注意,如果您在应用中使用多个 Firebase 库,我们强烈建议您使用 BoM 来管理库版本,从而确保所有版本都兼容。

    dependencies {
        // Add the dependency for the Firebase Authentication library
        // When NOT using the BoM, you must specify versions in Firebase library dependencies
        implementation("com.google.firebase:firebase-auth:23.0.0")
    }
    
    是否想要查找 Kotlin 专用的库模块?从 2023 年 10 月 (Firebase BoM 32.5.0) 开始,Kotlin 和 Java 开发者可以依赖于主库模块(如需了解详情,请参阅关于此计划的常见问题解答)。

创建一个基于密码的账号

如需创建具有密码的新用户账号,请在您应用的登录 Activity 中完成以下步骤:

  1. 在注册 Activity 的 onCreate 方法中,获取 FirebaseAuth 对象的共享实例:

    Kotlin+KTX

    private lateinit var auth: FirebaseAuth
    // ...
    // Initialize Firebase Auth
    auth = Firebase.auth

    Java

    private FirebaseAuth mAuth;
    // ...
    // Initialize Firebase Auth
    mAuth = FirebaseAuth.getInstance();
  2. 初始化您的 Activity 时,检查用户当前是否已登录:

    Kotlin+KTX

    public override fun onStart() {
        super.onStart()
        // Check if user is signed in (non-null) and update UI accordingly.
        val currentUser = auth.currentUser
        if (currentUser != null) {
            reload()
        }
    }

    Java

    @Override
    public void onStart() {
        super.onStart();
        // Check if user is signed in (non-null) and update UI accordingly.
        FirebaseUser currentUser = mAuth.getCurrentUser();
        if(currentUser != null){
            reload();
        }
    }
  3. 在新用户使用您的应用注册表单注册时,完成您的应用要求的所有新账号验证步骤,例如验证新账号的密码是否输入正确并且符合您的密码复杂度要求。
  4. 将新用户的电子邮件地址和密码传递给 createUserWithEmailAndPassword 方法,以创建一个新账号:

    Kotlin+KTX

    auth.createUserWithEmailAndPassword(email, password)
        .addOnCompleteListener(this) { task ->
            if (task.isSuccessful) {
                // Sign in success, update UI with the signed-in user's information
                Log.d(TAG, "createUserWithEmail:success")
                val user = auth.currentUser
                updateUI(user)
            } else {
                // If sign in fails, display a message to the user.
                Log.w(TAG, "createUserWithEmail:failure", task.exception)
                Toast.makeText(
                    baseContext,
                    "Authentication failed.",
                    Toast.LENGTH_SHORT,
                ).show()
                updateUI(null)
            }
        }

    Java

    mAuth.createUserWithEmailAndPassword(email, password)
            .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, "createUserWithEmail:success");
                        FirebaseUser user = mAuth.getCurrentUser();
                        updateUI(user);
                    } else {
                        // If sign in fails, display a message to the user.
                        Log.w(TAG, "createUserWithEmail:failure", task.getException());
                        Toast.makeText(EmailPasswordActivity.this, "Authentication failed.",
                                Toast.LENGTH_SHORT).show();
                        updateUI(null);
                    }
                }
            });
    如果新账号创建成功,则该用户也会同时登录。在该回调函数中,您可以使用 getCurrentUser 方法来获取用户的账号数据。

让用户使用电子邮件地址和密码登录

让用户使用密码登录的步骤与创建新账号的步骤类似。在您应用的登录 Activity 中,执行以下操作:

  1. 在登录 Activity 的 onCreate 方法中,获取 FirebaseAuth 对象的共享实例:

    Kotlin+KTX

    private lateinit var auth: FirebaseAuth
    // ...
    // Initialize Firebase Auth
    auth = Firebase.auth

    Java

    private FirebaseAuth mAuth;
    // ...
    // Initialize Firebase Auth
    mAuth = FirebaseAuth.getInstance();
  2. 初始化您的 Activity 时,检查用户当前是否已登录:

    Kotlin+KTX

    public override fun onStart() {
        super.onStart()
        // Check if user is signed in (non-null) and update UI accordingly.
        val currentUser = auth.currentUser
        if (currentUser != null) {
            reload()
        }
    }

    Java

    @Override
    public void onStart() {
        super.onStart();
        // Check if user is signed in (non-null) and update UI accordingly.
        FirebaseUser currentUser = mAuth.getCurrentUser();
        if(currentUser != null){
            reload();
        }
    }
  3. 在用户登录您的应用时,将该用户的电子邮件地址和密码传递给 signInWithEmailAndPassword

    Kotlin+KTX

    auth.signInWithEmailAndPassword(email, password)
        .addOnCompleteListener(this) { task ->
            if (task.isSuccessful) {
                // Sign in success, update UI with the signed-in user's information
                Log.d(TAG, "signInWithEmail:success")
                val user = auth.currentUser
                updateUI(user)
            } else {
                // If sign in fails, display a message to the user.
                Log.w(TAG, "signInWithEmail:failure", task.exception)
                Toast.makeText(
                    baseContext,
                    "Authentication failed.",
                    Toast.LENGTH_SHORT,
                ).show()
                updateUI(null)
            }
        }

    Java

    mAuth.signInWithEmailAndPassword(email, password)
            .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, "signInWithEmail:success");
                        FirebaseUser user = mAuth.getCurrentUser();
                        updateUI(user);
                    } else {
                        // If sign in fails, display a message to the user.
                        Log.w(TAG, "signInWithEmail:failure", task.getException());
                        Toast.makeText(EmailPasswordActivity.this, "Authentication failed.",
                                Toast.LENGTH_SHORT).show();
                        updateUI(null);
                    }
                }
            });
    如果登录成功,您可以使用返回的 FirebaseUser 继续操作。

建议:设置密码政策

您可以强制实施密码复杂度要求,从而提高账号安全性。

如需为项目配置密码政策,请打开 Firebase 控制台的“身份验证设置”页面上的密码政策标签页:

身份验证设置

Firebase Authentication 密码政策支持以下密码要求:

  • 必须包含小写字符

  • 必须包含大写字符

  • 必须包含数字字符

  • 必须包含非字母数字字符

    以下字符符合非字母数字字符要求:^ $ * . [ ] { } ( ) ? " ! @ # % & / \ , > < ' : ; | _ ~

  • 最小密码长度(介于 6 到 30 个字符之间;默认为 6)

  • 最大密码长度(上限为 4096 个字符)

您可以通过两种模式启用密码政策强制执行:

  • 要求:尝试登录会失败,直到用户将密码更新为符合您的政策的密码。

  • 通知:允许用户使用不符合要求的密码登录。使用此模式时,您应检查用户的密码是否符合客户端的政策,并以某种方式提示用户更新密码(如果密码不符合政策)。

新用户始终需要选择符合您政策的密码。

如果您有活跃用户,我们建议您不要启用强制模式,除非您打算禁止密码不符合政策的用户访问您的应用。请改用通知模式,让用户使用当前密码登录,并告知他们密码不符合哪些要求。

推荐做法:启用电子邮件枚举保护

如果您必须注册一个电子邮件地址(例如,当使用电子邮件地址和密码登录时)但未注册,或者如果电子邮件地址不应该被使用(例如,当更改用户的电子邮件地址时)但已注册,一些将电子邮件地址作为参数的 Firebase Authentication 方法会抛出具体的错误。虽然这对于向用户建议具体的补救措施非常有用,但恶意操作者也可能会滥用该功能,以发现用户注册的电子邮件地址。

为了降低这种风险,我们建议您使用 Google Cloud gcloud 工具为您的项目启用电子邮件枚举保护。请注意,启用此功能会更改 Firebase Authentication 的错误报告行为:请确保您的应用不依赖于更具体的错误。

后续步骤

在用户首次登录后,系统会创建一个新的用户账号,并将其与该用户登录时使用的凭据(即用户名和密码、电话号码或者身份验证提供方信息)相关联。此新账号存储在您的 Firebase 项目中,无论用户采用何种方式登录,您项目中的每个应用都可以使用此账号来识别用户。

  • 在您的应用中,您可以从 FirebaseUser 对象获取用户的基本个人资料信息。请参阅管理用户

  • 在您的 Firebase Realtime DatabaseCloud Storage 安全规则中,您可以从 auth 变量获取已登录用户的唯一用户 ID,然后利用此 ID 来控制用户可以访问哪些数据。

您可以通过将身份验证提供方凭据关联至现有用户账号,让用户可以使用多个身份验证提供方登录您的应用。

如需将用户退出登录,请调用 signOut

Kotlin+KTX

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();