Autenticar com o Firebase usando link por e-mail no Android

Use o Firebase Authentication para fazer o login de um usuário por um link enviado a ele por e-mail. Nesse processo, o endereço de e-mail do usuário também é verificado.

O login por e-mail tem inúmeros benefícios:

  • Inscrição e login simplificados.
  • Menos chances de reutilizar senhas entre os aplicativos, o que pode diminuir a segurança até mesmo das senhas mais fortes.
  • Capacidade de autenticar o usuário e verificar se ele é o legítimo proprietário do endereço de e-mail.
  • O usuário só precisa de uma conta de e-mail acessível para fazer login. Não são necessários números de telefone nem contas em redes sociais.
  • O usuário faz login com segurança sem precisar fornecer ou lembrar de uma senha. Em dispositivos móveis, isso é bem importante porque facilita a vida do usuário.
  • O usuário que já tiver feito login com um identificador de e-mail (senha ou federado) poderá se conectar depois apenas com o e-mail. Por exemplo, se ele se esquecer da senha, ainda será possível fazer login sem precisar redefini-la.

Antes de começar

Configurar seu projeto do Android

  1. Adicione o Firebase ao projeto para Android, caso ainda não tenha feito isso.

  2. No arquivo Gradle do módulo (nível do app) (geralmente <project>/<app-module>/build.gradle.kts ou <project>/<app-module>/build.gradle), adicione a dependência da biblioteca do Firebase Authentication para Android. Recomendamos o uso do Firebase Android BoM para controlar o controle de versões da biblioteca.

    Além disso, como parte da configuração do Firebase Authentication, é necessário adicionar o SDK do Google Play Services ao seu app.

    dependencies {
        // Import the BoM for the Firebase platform
        implementation(platform("com.google.firebase:firebase-bom:33.8.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:21.3.0")
    }

    Com a Firebase Android BoM, seu app sempre vai usar versões compatíveis das bibliotecas do Firebase para Android.

    (Alternativa) Adicionar dependências das bibliotecas do Firebase sem usar o BoM

    Se você preferir não usar o Firebase BoM, especifique cada versão das bibliotecas do Firebase na linha de dependência correspondente.

    Se você usa várias bibliotecas do Firebase no app, recomendamos utilizar o BoM para gerenciar as versões delas, porque isso ajuda a garantir a compatibilidade de todas as bibliotecas.

    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.1.0")
    // Also add the dependency for the Google Play services library and specify its version implementation("com.google.android.gms:play-services-auth:21.3.0")
    }
    Está procurando um módulo de biblioteca específico do Kotlin? A partir de outubro de 2023 (Firebase BoM 32.5.0), os desenvolvedores Kotlin e Java poderão depender do módulo da biblioteca principal. Para mais detalhes, consulte Perguntas frequentes sobre essa iniciativa).

Ativar o login por link de e-mail no projeto do Firebase

Para que os usuários façam login usando um link enviado por e-mail, primeiro ative o provedor de e-mail e o método de login por link no projeto do Firebase:

  1. No console do Firebase, abra a seção Auth.
  2. Na guia Método de login, ative o provedor de E-mail/senha. Ative esse método para poder usar o login por link de e-mail.
  3. Na mesma seção, ative o método Link do e-mail (login sem senha).
  4. Clique em Salvar.

Para iniciar o fluxo de autenticação, apresente ao usuário uma interface que solicite o endereço de e-mail e chame sendSignInLinkToEmail para solicitar que o Firebase envie o link de autenticação para o e-mail do usuário.

  1. Crie o objeto ActionCodeSettings, que fornece instruções ao Firebase para gerar o link do e-mail. Defina os seguintes campos:

    • url: o link direto para incorporar e qualquer estado adicional a ser transmitido. É preciso que o domínio do link esteja na lista de permissões de domínios autorizados do Console do Firebase, encontrada na guia Método de login (Autenticação -> Método de login). O link vai redirecionar o usuário para esse URL se o app não estiver instalado e se não for possível fazer a instalação dele no dispositivo.
    • androidPackageName e iOSBundleId: ajudam Firebase Authentication a determinar se é necessário criar um link somente para Web ou para dispositivos móveis que é aberto em um dispositivo Android ou Apple.
    • handleCodeInApp: definido como verdadeiro. É necessário sempre concluir o processo de login no app, ao contrário de outras ações fora de banda, como redefinição de senha e verificação de e-mail. Isso acontece porque o usuário precisa estar conectado e com o estado Auth mantido no app ao final do fluxo.
    • linkDomain: quando domínios de link Hosting personalizados são definidos para um projeto, especifique qual deles usar quando o link for aberto por um app para dispositivos móveis especificado. Caso contrário, o domínio padrão será selecionado automaticamente (por exemplo, PROJECT_ID.firebaseapp.com).
    • dynamicLinkDomain: Descontinuado. Não especifique esse parâmetro.

    Kotlin

    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
        )
    }

    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();

    Para saber mais sobre ActionCodeSettings, consulte a seção Como transmitir o estado nas ações de e-mail.

  2. Solicite o e-mail ao usuário.

  3. Envie o link de autenticação a esse endereço e salve o e-mail caso o usuário conclua o login no mesmo dispositivo.

    Kotlin

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

    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.");
                    }
                }
            });

Preocupações com segurança

No Firebase Authentication, o usuário precisa fornecer o endereço de e-mail ao concluir o fluxo de login. Isso evita que o link seja usado para fazer o login de um usuário indesejado ou em um dispositivo não intencional. Para realizar o login, esse endereço precisa ser igual ao e-mail que recebeu o link.

É possível simplificar o fluxo dos usuários que abrem o link no mesmo dispositivo usado para solicitá-lo. Basta armazenar o endereço deles localmente quando enviar o e-mail de login. Por exemplo, você pode usar o SharedPreferences. Depois, utilize o endereço para concluir o fluxo. Não transmita o e-mail do usuário nos parâmetros de URL de redirecionamento e nem o reutilize, já que isso pode ativar injeções de sessão.

Após a conclusão do login, qualquer mecanismo anterior de login não verificado será removido do usuário, e todas as sessões atuais serão invalidadas. Por exemplo, se alguém tiver criado uma conta não verificada com a mesma senha e e-mail, a senha do usuário será removida. Isso impede que a pessoa que reivindicou a propriedade e criou essa conta faça login novamente com o e-mail e senha não confirmados.

Além disso, não deixe de usar um URL HTTPS na produção para impedir que o link possa ser interceptado por servidores intermediários.

Como concluir o login em um app Android

O Firebase Authentication usa Firebase Hosting para enviar o link por e-mail a um dispositivo móvel. No aplicativo para dispositivos móveis, ele precisa estar configurado para detectar o link de entrada, analisar o link direto e então concluir o login. Para saber mais, consulte a documentação sobre links de apps para Android.

Configurar o Firebase Hosting

O Firebase Authentication usa domínios do Firebase Hosting ao criar e enviar um link que deve ser aberto em um aplicativo para dispositivos móveis. Um domínio padrão do Firebase Hosting já foi configurado para você.

  1. Configure os domínios do Firebase Hosting:

    No Firebaseconsole do , abra a seção Autenticação.

    • Se você quiser usar o domínio padrão para o link de e-mail que é aberto em aplicativos para dispositivos móveis, acesse o site padrão e anote o domínio padrão do Hosting. Um domínio Hosting padrão geralmente é assim: PROJECT_ID.firebaseapp.com.

      Você vai precisar desse valor ao configurar o app para interceptar o link recebido.

    • Se você quiser usar um domínio personalizado para o link de e-mail, registre um com Firebase Hosting e use-o para o domínio do link.

  2. Configurar apps Android:

    Para processar esses links do app Android, o nome do pacote do app precisa ser especificado nas configurações do projeto do console Firebase. Além disso, o SHA-1 e o SHA-256 do certificado do aplicativo precisam ser fornecidos.

    Se você quiser que esses links redirecionem para uma atividade específica, será necessário configurar um filtro de intent no arquivo AndroidManifest.xml. O filtro de intent precisa capturar links diretos do seu domínio. Em AndroidManifest.xml:

    <intent-filter android:autoVerify="true">
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.BROWSABLE" />
      <category android:name="android.intent.category.DEFAULT" />
      <data
        android:scheme="https"
        android:host="<PROJECT_ID>.firebaseapp.com or your custom domain"
        android:pathPrefix="/__/auth/links" />
    </intent-filter>
    

    Quando os usuários abrem um link de hospedagem com o caminho /__/auth/links e o esquema e o host especificados, o app inicia a atividade usando esse filtro de intent para processar o link.

Depois de receber o link conforme descrito acima, verifique se ele é destinado à autenticação por e-mail e conclua o login.

Kotlin

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)
            }
        }
}

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());
                    }
                }
            });
}

Para saber mais sobre como processar o login com o link por e-mail em um app da Apple, consulte o guia de plataformas da Apple.

Para saber mais sobre como processar o login com o link por e-mail em um aplicativo da Web, consulte este guia.

Também é possível vincular este método de autenticação a um usuário atual. Por exemplo, um usuário já autenticado com outro provedor, como número de telefone, pode incluir este método de login na conta dele.

A diferença está na segunda metade da operação:

Kotlin

// 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)
        }
    }

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());
                }
            }
        });

Também é possível usá-lo para reautenticar um usuário de link por e-mail antes de executar uma operação confidencial.

Kotlin

// 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)
        }
    }

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());
                }
            }
        });

No entanto, este fluxo pode não ser concluído, já que ele pode terminar em um dispositivo diferente do que o usado para fazer login. Nesse caso, é possível exibir um erro ao usuário para obrigá-lo a abrir o link no mesmo dispositivo. Você pode transmitir um estado no link para fornecer informações sobre o tipo de operação e o UID do usuário.

A autenticação do link por e-mail dependia do Firebase Dynamic Links, que será desativado em 25 de agosto de 2025.

Publicamos uma solução alternativa no SDK do Android Firebase Authentication v23.2.0+ e no Firebase BoM v33.9.0+.

Se o app usa os links antigos, migre o app para o novo sistema baseado em Firebase Hosting.

Se você criou o projeto em 15 de setembro de 2023 ou depois, a proteção contra enumeração de e-mails está ativada por padrão. Esse recurso aumenta a segurança das contas de usuário do projeto, mas desativa o método fetchSignInMethodsForEmail(), que anteriormente recomendamos para implementar fluxos que priorizam identificadores.

Embora você possa desativar a proteção contra enumeração de e-mails para o seu projeto, nós não recomendamos fazer isso.

Consulte a documentação sobre a proteção contra enumeração de e-mails para mais detalhes.

Próximas etapas

Depois que um usuário faz login pela primeira vez, uma nova conta de usuário é criada e vinculada às credenciais, que podem ser o número do telefone, o nome de usuário e a senha ou as informações do provedor de autenticação. Essa nova conta é armazenada como parte do projeto do Firebase e pode ser usada para identificar um usuário em todos os apps do projeto, seja qual for o método de login utilizado.

  • Você pode receber as informações básicas de perfil do usuário do objeto FirebaseUser nos seus aplicativos. Consulte Gerenciar usuários.

  • Nas Regras de segurança Firebase Realtime Database e Cloud Storage, você pode acessar o ID exclusivo do usuário conectado pela variável auth e usar essas informações para controlar quais dados um usuário pode acessar.

Os usuários podem fazer login no app usando vários provedores de autenticação. Basta vincular as credenciais desses provedores a uma conta de usuário.

Para desconectar um usuário, chame signOut:

Kotlin

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();