获取我们在 Firebase 峰会上发布的所有信息,了解 Firebase 可如何帮助您加快应用开发速度并满怀信心地运行应用。了解详情

Autenticarse con Firebase usando un enlace de correo electrónico en Android

Puede usar Firebase Authentication para iniciar sesión en un usuario enviándole un correo electrónico que contenga un enlace, en el que puede hacer clic para iniciar sesión. En el proceso, también se verifica la dirección de correo electrónico del usuario.

Hay numerosos beneficios al iniciar sesión por correo electrónico:

  • Registro e inicio de sesión de baja fricción.
  • Menor riesgo de reutilización de contraseñas entre aplicaciones, lo que puede socavar la seguridad incluso de contraseñas bien seleccionadas.
  • La capacidad de autenticar a un usuario y al mismo tiempo verificar que el usuario es el propietario legítimo de una dirección de correo electrónico.
  • Un usuario solo necesita una cuenta de correo electrónico accesible para iniciar sesión. No se requiere la propiedad de un número de teléfono o cuenta de redes sociales.
  • Un usuario puede iniciar sesión de forma segura sin necesidad de proporcionar (o recordar) una contraseña, lo que puede resultar engorroso en un dispositivo móvil.
  • Un usuario existente que haya iniciado sesión previamente con un identificador de correo electrónico (contraseña o federado) puede actualizarse para iniciar sesión solo con el correo electrónico. Por ejemplo, un usuario que ha olvidado su contraseña aún puede iniciar sesión sin necesidad de restablecer su contraseña.

Antes de que empieces

Configura tu proyecto de Android

  1. Si aún no lo ha hecho, agregue Firebase a su proyecto de Android .

  2. En el archivo Gradle de tu módulo (nivel de aplicación) (generalmente <project>/<app-module>/build.gradle ), agrega la dependencia para la biblioteca de Android Firebase Authentication. Recomendamos usar Firebase Android BoM para controlar el control de versiones de la biblioteca.

    Además, como parte de la configuración de Firebase Authentication, debe agregar el SDK de servicios de Google Play a su aplicación.

    Java

    dependencies {
        // Import the BoM for the Firebase platform
        implementation platform('com.google.firebase:firebase-bom:31.1.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'
    // Also add the dependency for the Google Play services library and specify its version implementation 'com.google.android.gms:play-services-auth:20.4.0'
    }

    Al usar Firebase Android BoM , su aplicación siempre usará versiones compatibles de las bibliotecas de Firebase Android.

    (Alternativa) Agregar dependencias de la biblioteca de Firebase sin usar el BoM

    Si elige no usar Firebase BoM, debe especificar cada versión de la biblioteca de Firebase en su línea de dependencia.

    Tenga en cuenta que si usa varias bibliotecas de Firebase en su aplicación, le recomendamos enfáticamente que use la lista de materiales para administrar las versiones de la biblioteca, lo que garantiza que todas las versiones sean compatibles.

    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:21.1.0'
    // Also add the dependency for the Google Play services library and specify its version implementation 'com.google.android.gms:play-services-auth:20.4.0'
    }

    Kotlin+KTX

    dependencies {
        // Import the BoM for the Firebase platform
        implementation platform('com.google.firebase:firebase-bom:31.1.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-ktx'
    // Also add the dependency for the Google Play services library and specify its version implementation 'com.google.android.gms:play-services-auth:20.4.0'
    }

    Al usar Firebase Android BoM , su aplicación siempre usará versiones compatibles de las bibliotecas de Firebase Android.

    (Alternativa) Agregar dependencias de la biblioteca de Firebase sin usar el BoM

    Si elige no usar Firebase BoM, debe especificar cada versión de la biblioteca de Firebase en su línea de dependencia.

    Tenga en cuenta que si usa varias bibliotecas de Firebase en su aplicación, le recomendamos enfáticamente que use la lista de materiales para administrar las versiones de la biblioteca, lo que garantiza que todas las versiones sean compatibles.

    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-ktx:21.1.0'
    // Also add the dependency for the Google Play services library and specify its version implementation 'com.google.android.gms:play-services-auth:20.4.0'
    }

Para que los usuarios inicien sesión mediante un enlace de correo electrónico, primero debe habilitar el proveedor de correo electrónico y el método de inicio de sesión con enlace de correo electrónico para su proyecto de Firebase:

  1. En Firebase console , abra la sección Auth .
  2. En la pestaña Método de inicio de sesión , habilite el proveedor de correo electrónico/contraseña . Tenga en cuenta que el inicio de sesión con correo electrónico/contraseña debe estar habilitado para usar el inicio de sesión con enlace de correo electrónico.
  3. En la misma sección, habilite el método de inicio de sesión Enlace de correo electrónico (inicio de sesión sin contraseña) .
  4. Haga clic en Guardar .

Para iniciar el flujo de autenticación, presente al usuario una interfaz que le solicite que proporcione su dirección de correo electrónico y luego llame a sendSignInLinkToEmail para solicitar que Firebase envíe el enlace de autenticación al correo electrónico del usuario.

  1. Construya el objeto ActionCodeSettings , que proporciona a Firebase instrucciones sobre cómo construir el enlace de correo electrónico. Configure los siguientes campos:

    • url : el enlace profundo para incrustar y cualquier estado adicional que se transmita. El dominio del vínculo debe incluirse en la lista blanca de la lista de dominios autorizados de Firebase Console, que se puede encontrar yendo a la pestaña Método de inicio de sesión (Autenticación -> Método de inicio de sesión). El enlace redirigirá al usuario a esta URL si la aplicación no está instalada en su dispositivo y no se pudo instalar.
    • androidPackageName e IOSBundleId : las aplicaciones que se usarán cuando se abra el enlace de inicio de sesión en un dispositivo Android o Apple. Obtenga más información sobre cómo configurar Firebase Dynamic Links para abrir vínculos de acción de correo electrónico a través de aplicaciones móviles.
    • handleCodeInApp : establecido en verdadero. La operación de inicio de sesión siempre debe completarse en la aplicación, a diferencia de otras acciones de correo electrónico fuera de banda (restablecimiento de contraseña y verificaciones de correo electrónico). Esto se debe a que, al final del flujo, se espera que el usuario haya iniciado sesión y su estado de autenticación persista dentro de la aplicación.
    • dynamicLinkDomain : cuando se definen varios dominios de enlace dinámico personalizados para un proyecto, especifique cuál usar cuando el enlace se abra a través de una aplicación móvil específica (por ejemplo, example.page.link ). De lo contrario, el primer dominio se selecciona automáticamente.

    Java

    ActionCodeSettings actionCodeSettings =
            ActionCodeSettings.newBuilder()
                    // URL you want to redirect back to. The domain (www.example.com) for this
                    // URL must be whitelisted in the Firebase Console.
                    .setUrl("https://www.example.com/finishSignUp?cartId=1234")
                    // This must be true
                    .setHandleCodeInApp(true)
                    .setIOSBundleId("com.example.ios")
                    .setAndroidPackageName(
                            "com.example.android",
                            true, /* installIfNotAvailable */
                            "12"    /* minimumVersion */)
                    .build();

    Kotlin+KTX

    val actionCodeSettings = actionCodeSettings {
        // URL you want to redirect back to. The domain (www.example.com) for this
        // URL must be whitelisted in the Firebase Console.
        url = "https://www.example.com/finishSignUp?cartId=1234"
        // This must be true
        handleCodeInApp = true
        setIOSBundleId("com.example.ios")
        setAndroidPackageName(
                "com.example.android",
                true, /* installIfNotAvailable */
                "12" /* minimumVersion */)
    }

    Para obtener más información sobre ActionCodeSettings, consulte la sección Passing State in Email Actions .

  2. Pide al usuario su correo electrónico.

  3. Envíe el enlace de autenticación al correo electrónico del usuario y guarde el correo electrónico del usuario en caso de que el usuario complete el inicio de sesión de correo electrónico en el mismo dispositivo.

    Java

    FirebaseAuth auth = FirebaseAuth.getInstance();
    auth.sendSignInLinkToEmail(email, actionCodeSettings)
            .addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "Email sent.");
                    }
                }
            });

    Kotlin+KTX

    Firebase.auth.sendSignInLinkToEmail(email, actionCodeSettings)
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    Log.d(TAG, "Email sent.")
                }
            }

Preocupaciones de seguridad

Para evitar que se use un enlace de inicio de sesión para iniciar sesión como un usuario no deseado o en un dispositivo no deseado, Firebase Auth requiere que se proporcione la dirección de correo electrónico del usuario al completar el flujo de inicio de sesión. Para que el inicio de sesión sea exitoso, esta dirección de correo electrónico debe coincidir con la dirección a la que se envió originalmente el enlace de inicio de sesión.

Puede simplificar este flujo para los usuarios que abren el enlace de inicio de sesión en el mismo dispositivo en el que solicitan el enlace, almacenando su dirección de correo electrónico localmente, por ejemplo, usando SharedPreferences, cuando envía el correo electrónico de inicio de sesión. Luego, use esta dirección para completar el flujo. No pase el correo electrónico del usuario en los parámetros de la URL de redireccionamiento y reutilícelo, ya que esto puede permitir inyecciones de sesión.

Después de completar el inicio de sesión, cualquier mecanismo de inicio de sesión no verificado anterior se eliminará del usuario y se invalidarán todas las sesiones existentes. Por ejemplo, si alguien creó anteriormente una cuenta no verificada con el mismo correo electrónico y contraseña, la contraseña del usuario se eliminará para evitar que el suplantador que reclamó la propiedad y creó esa cuenta no verificada vuelva a iniciar sesión con el correo electrónico y la contraseña no verificados.

También asegúrese de usar una URL HTTPS en producción para evitar que su enlace sea potencialmente interceptado por servidores intermediarios.

Completar el inicio de sesión en una aplicación de Android

Firebase Authentication usa Firebase Dynamic Links para enviar el vínculo del correo electrónico a un dispositivo móvil. Para completar el inicio de sesión a través de la aplicación móvil, la aplicación debe configurarse para detectar el enlace de la aplicación entrante, analizar el enlace profundo subyacente y luego completar el inicio de sesión.

Firebase Auth usa Firebase Dynamic Links cuando envía un enlace que debe abrirse en una aplicación móvil. Para utilizar esta función, se deben configurar Dynamic Links en Firebase Console.

  1. Habilite los vínculos dinámicos de Firebase:

    1. En Firebase console , abra la sección Dynamic Links .
    2. Si aún no ha aceptado los términos de Dynamic Links y ha creado un dominio de Dynamic Links, hágalo ahora.

      Si ya creó un dominio de Dynamic Links, tome nota. Un dominio de Dynamic Links normalmente se parece al siguiente ejemplo:

      example.page.link

      Necesitará este valor cuando configure su aplicación Apple o Android para interceptar el enlace entrante.

  2. Configuración de aplicaciones Android:

    1. Para manejar estos enlaces desde su aplicación de Android, el nombre del paquete de Android debe especificarse en la configuración del proyecto de Firebase Console. Además, se debe proporcionar el SHA-1 y SHA-256 del certificado de la aplicación.
    2. Ahora que ha agregado un dominio de vínculo dinámico y se ha asegurado de que su aplicación de Android esté configurada correctamente, el vínculo dinámico redirigirá a su aplicación, comenzando desde la actividad del iniciador.
    3. Si desea que el enlace dinámico redirija a una actividad específica, deberá configurar un filtro de intención en su archivo AndroidManifest.xml . Esto se puede hacer especificando su dominio de enlace dinámico o el controlador de acciones de correo electrónico en el filtro de intención. De forma predeterminada, el controlador de acciones de correo electrónico está alojado en un dominio como el siguiente ejemplo:
      PROJECT_ID.firebaseapp.com/
    4. Advertencias:
      1. No especifique la URL que configuró en actionCodeSettings en su filtro de intenciones.
      2. Al crear su dominio de enlace dinámico, es posible que también haya creado un enlace URL corto. Esta URL corta no se transmitirá; no configure su filtro de intenciones para capturarlo con un atributo android:pathPrefix . Esto significa que no podrá capturar diferentes enlaces dinámicos en diferentes partes de su aplicación. Sin embargo, puede verificar el parámetro de consulta de mode en el enlace para ver qué operación se está intentando realizar, o usar métodos SDK como isSignInWithEmailLink para ver si un enlace que recibió su aplicación hace lo que desea.
    5. Para obtener más información sobre cómo recibir enlaces dinámicos, consulte las instrucciones para recibir enlaces dinámicos de Android .

Después de recibir el enlace como se describe arriba, verifique que sea para la autenticación del enlace de correo electrónico y complete el inicio de sesión.

Java

FirebaseAuth auth = FirebaseAuth.getInstance();
Intent intent = getIntent();
String emailLink = intent.getData().toString();

// Confirm the link is a sign-in with email link.
if (auth.isSignInWithEmailLink(emailLink)) {
    // Retrieve this from wherever you stored it
    String email = "someemail@domain.com";

    // The client SDK will parse the code from the link for you.
    auth.signInWithEmailLink(email, emailLink)
            .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "Successfully signed in with email link!");
                        AuthResult result = task.getResult();
                        // You can access the new user via result.getUser()
                        // Additional user info profile *not* available via:
                        // result.getAdditionalUserInfo().getProfile() == null
                        // You can check if the user is new or existing:
                        // result.getAdditionalUserInfo().isNewUser()
                    } else {
                        Log.e(TAG, "Error signing in with email link", task.getException());
                    }
                }
            });
}

Kotlin+KTX

val auth = Firebase.auth
val intent = intent
val emailLink = intent.data.toString()

// Confirm the link is a sign-in with email link.
if (auth.isSignInWithEmailLink(emailLink)) {
    // Retrieve this from wherever you stored it
    val email = "someemail@domain.com"

    // The client SDK will parse the code from the link for you.
    auth.signInWithEmailLink(email, emailLink)
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    Log.d(TAG, "Successfully signed in with email link!")
                    val result = task.result
                    // You can access the new user via result.getUser()
                    // Additional user info profile *not* available via:
                    // result.getAdditionalUserInfo().getProfile() == null
                    // You can check if the user is new or existing:
                    // result.getAdditionalUserInfo().isNewUser()
                } else {
                    Log.e(TAG, "Error signing in with email link", task.exception)
                }
            }
}

Para obtener más información sobre cómo manejar el inicio de sesión con un enlace de correo electrónico en una aplicación de Apple, consulte la guía de plataformas de Apple .

Para obtener información sobre cómo manejar el inicio de sesión con un enlace de correo electrónico en una aplicación web, consulte la guía web .

También puede vincular este método de autenticación a un usuario existente. Por ejemplo, un usuario previamente autenticado con otro proveedor, como un número de teléfono, puede agregar este método de inicio de sesión a su cuenta existente.

La diferencia estaría en la segunda mitad de la operación:

Java

// Construct the email link credential from the current URL.
AuthCredential credential =
        EmailAuthProvider.getCredentialWithLink(email, emailLink);

// Link the credential to the current user.
auth.getCurrentUser().linkWithCredential(credential)
        .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    Log.d(TAG, "Successfully linked emailLink credential!");
                    AuthResult result = task.getResult();
                    // You can access the new user via result.getUser()
                    // Additional user info profile *not* available via:
                    // result.getAdditionalUserInfo().getProfile() == null
                    // You can check if the user is new or existing:
                    // result.getAdditionalUserInfo().isNewUser()
                } else {
                    Log.e(TAG, "Error linking emailLink credential", task.getException());
                }
            }
        });

Kotlin+KTX

// Construct the email link credential from the current URL.
val credential = EmailAuthProvider.getCredentialWithLink(email, emailLink)

// Link the credential to the current user.
Firebase.auth.currentUser!!.linkWithCredential(credential)
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                Log.d(TAG, "Successfully linked emailLink credential!")
                val result = task.result
                // You can access the new user via result.getUser()
                // Additional user info profile *not* available via:
                // result.getAdditionalUserInfo().getProfile() == null
                // You can check if the user is new or existing:
                // result.getAdditionalUserInfo().isNewUser()
            } else {
                Log.e(TAG, "Error linking emailLink credential", task.exception)
            }
        }

Esto también se puede usar para volver a autenticar a un usuario de enlace de correo electrónico antes de ejecutar una operación confidencial.

Java

// Construct the email link credential from the current URL.
AuthCredential credential =
        EmailAuthProvider.getCredentialWithLink(email, emailLink);

// Re-authenticate the user with this credential.
auth.getCurrentUser().reauthenticateAndRetrieveData(credential)
        .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    // User is now successfully reauthenticated
                } else {
                    Log.e(TAG, "Error reauthenticating", task.getException());
                }
            }
        });

Kotlin+KTX

// Construct the email link credential from the current URL.
val credential = EmailAuthProvider.getCredentialWithLink(email, emailLink)

// Re-authenticate the user with this credential.
Firebase.auth.currentUser!!.reauthenticateAndRetrieveData(credential)
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                // User is now successfully reauthenticated
            } else {
                Log.e(TAG, "Error reauthenticating", task.exception)
            }
        }

Sin embargo, como el flujo podría terminar en un dispositivo diferente donde el usuario original no inició sesión, es posible que este flujo no se complete. En ese caso, se le puede mostrar un error al usuario para obligarlo a abrir el enlace en el mismo dispositivo. Se puede pasar algún estado en el enlace para proporcionar información sobre el tipo de operación y el uid del usuario.

En caso de que admita el inicio de sesión basado en contraseña y enlace con correo electrónico, para diferenciar el método de inicio de sesión para un usuario de contraseña/enlace, use fetchSignInMethodsForEmail . Esto es útil para los flujos de identificador primero donde primero se le pide al usuario que proporcione su correo electrónico y luego se le presenta el método de inicio de sesión:

Java

auth.fetchSignInMethodsForEmail(email)
        .addOnCompleteListener(new OnCompleteListener<SignInMethodQueryResult>() {
            @Override
            public void onComplete(@NonNull Task<SignInMethodQueryResult> task) {
                if (task.isSuccessful()) {
                    SignInMethodQueryResult result = task.getResult();
                    List<String> signInMethods = result.getSignInMethods();
                    if (signInMethods.contains(EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD)) {
                        // User can sign in with email/password
                    } else if (signInMethods.contains(EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD)) {
                        // User can sign in with email/link
                    }
                } else {
                    Log.e(TAG, "Error getting sign in methods for user", task.getException());
                }
            }
        });

Kotlin+KTX

Firebase.auth.fetchSignInMethodsForEmail(email)
        .addOnSuccessListener { result ->
            val signInMethods = result.signInMethods!!
            if (signInMethods.contains(EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD)) {
                // User can sign in with email/password
            } else if (signInMethods.contains(EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD)) {
                // User can sign in with email/link
            }
        }
        .addOnFailureListener { exception ->
            Log.e(TAG, "Error getting sign in methods for user", exception)
        }

Como se describe anteriormente, el correo electrónico/contraseña y el correo electrónico/enlace se consideran el mismo EmailAuthProvider (mismo PROVIDER_ID ) con diferentes métodos de inicio de sesión.

Próximos pasos

Después de que un usuario inicia sesión por primera vez, se crea una nueva cuenta de usuario y se vincula a las credenciales (es decir, el nombre de usuario y la contraseña, el número de teléfono o la información del proveedor de autenticación) con las que el usuario inició sesión. Esta nueva cuenta se almacena como parte de su proyecto de Firebase y se puede usar para identificar a un usuario en cada aplicación de su proyecto, independientemente de cómo inicie sesión el usuario.

  • En sus aplicaciones, puede obtener la información básica del perfil del usuario del objeto FirebaseUser . Consulte Administrar usuarios .

  • En sus Reglas de seguridad de Firebase Realtime Database y Cloud Storage, puede obtener el ID de usuario único del usuario que inició sesión de la variable auth y usarlo para controlar a qué datos puede acceder un usuario.

Puede permitir que los usuarios inicien sesión en su aplicación utilizando varios proveedores de autenticación vinculando las credenciales del proveedor de autenticación a una cuenta de usuario existente.

Para cerrar la sesión de un usuario, llame a signOut :

Java

FirebaseAuth.getInstance().signOut();

Kotlin+KTX

Firebase.auth.signOut()